i wrote a own Security Manager and my problem is, that i run code from other users in my program, and i have to ensure that there is no abuse.
So my Question is: How i am able to find out in the Methods of the Security Manager , who asks for the Access in the checkXXXXX() - methods.
Thanks
No there is no simple way to do this in the general case.
(If you were running within a web container, that might provide a way to get hold of the current request's authentication details. But that doesn't sound like your use-case.)
I guess there are a variety of ways that you could attempt to implement this, though you'd need to be careful to protect against code that spoofs the user identity. One idea is to associate each user identity with a distinct ThreadGroup, and get your security manager to block creation of threads in other thread groups; read the javadoc for Thread(ThreadGroup group, Runnable target, String name), paying attention to what it says about the thread group check.
Related
I'm using Vaadin Flow to develop a web app with Java. I would like to know the best way to handle login and authorization. I've been giving this a thought and I'm not sure the best way to do this.
I have a login view and a main app view with a content holder for nested layouts.
How do I check that the user is logged in and what permissions does it have to see or not see some part of the app? I've read about BeforeEnterEvent and ReRouting but it's still not very clear.
Do I have to use BeforeEnterEvent for each class I have? Do I have to create a class with user parameters like a boolean to check if it's logged in and a string for the kind of authorization it has? And where do I create or save this instance?
Is there a simple way to do this? Like to start with an empty layout and to start that with the login screen, then the login screen decides to swap for the main app view? And how do I prevent the user to type the address of the main view in the bar and access parts it shouldn't access like: /app/adminsettings
I'm sure this is way simpler but I think I have my head overloaded by now, thanks anyone in advance!
As always, there are no silver bullets. The "best way" always depends on
the requirements and your options range from Basic Auth to some external
OIDC provider.
There are already some tutorials out there with the most prominent from
Vaadin itself about Spring
Security
(which in a previous iteration had a flaw that compromised security,
which of course shows again, that security is no product but a process
and demands constant validation).
So I want to strategize here a bit more about the problems you are
facing and some things to consider:
Be aware, that when you use a security library, that has or allows for
an web path centric approach, that you should only use it for the
root and to open up paths to resources etc. The history API may only
look like you are fetching URLs from a server or web sockets may be
used under the hood and suddenly those rules no longer apply.
If you are using the annotation based way to add routes, you end up
with all the routes, that are there, for your UI per user. So it's
good to familiarize yourself with how to register routes
dynamically.
E.g. only add the routes the user is allowed on login; this usually
also has implications for the UI (e.g. menu entries).
There usually is some initial "declarative" security part (can the
user even enter this view; this usually means some simple role check).
A good place to check for this is a BeforeEnterListener added to the
UI; it will be called before any navigation to any view. See
navigation
livecyle
The next entry point(s) to guard are the BeforeEnterEvent you can
listen on in the view itself and/or maybe it implements
HasUrlParameter. If you take params from the "request" or the path,
the usually mean further checks (e.g. is the acting user allowed to
edit the blog entry with the id 42). See routing and URL
parameters
and also navigation
livecyle.
Deeper into the application you end up with something more imperative,
that libraries often make appear declarative, because they generate
some code for you from some annotation (e.g. some AOP that generates
the code around your #SecurityCheck('${u.owner}==${currentUser}')
void save(User u) method, that checks for the role and whether the
User u belongs to the acting user).
Be very certain, that your IoC system/library/... sees those
annotation and generates the code accordingly. Only #Route e.g.
will get the full DI treatment with Vaadin+Spring - for the rest it's
your job that the DI-framework can do it's job (a NPE from a missed
#Autowired is spotted very quickly, but a security check not being
called, is not). The obvious way around this, is to be imperative and
write the code yourself instead of relying on it to be there.
If you have an anonymous system and then some login, make sure to send
users over to a fresh session (and therefor UI); not only does it
prevent a session fixation attack, but it also allows you put all your
route-setup and UI derivations according to security in one place at
the beginning of the UI creation. If you have state you want to carry
over, make it part of the URL, that your successful login process
sends them back to or park in the browsers local storage.
Recently I've been dealing with Sring Security trying to customize it in my own way. For instance, I managed to introduce my authorization logic into a request's execution flow to tell whether the current user is authorized to call some method or not. I've done so by injecting a PreInvocationAuthorizationAdvice object where its before method is called and I can tell if the process should continue or not.
Now I want to do the same for authentication. I would like to inject my code (somehow, somewhere) where I'll be asked if some specific method needs authentication or not. I know I can do this in WebSecurityConfigurerAdapter.configure by calling antMatchers, regexMatchers etc. But I would rather do this case by case, instead of grouping URLs.
Is there anyway to do this?
It almost sounds like you are treating the ACL like an aspect that can be reused on different data sets, and if that's the assumption I'm not sure it holds up.
Last time I built a large system that included permissions, the model was something like this.
You have a number of users
You have a number of resources
You have a number of operations that can be performed on resources.
You can define roles that define different permission-sets (set of operations)
You have a number of projects
The resources are scoped by projects (they have a projectId)
A user is assigned zero or more roles in each project (mappings)
A user's access to a resource depends on the user's roles in the project which owns the resource (this could be changed at runtime).
If user U wants to delete resource A, you therefore need to find out what project resource A belongs to, and if the effective permission-set of U (join all roles U may have in the project) contained the "Delete Resource" privileged.
You need to be extremely careful on the backend when writing your SQL/JPA queries, because you can never trust the client. This means that you can't POST the projectId and resourceId, you always have to start with the resourceId, see which project it belongs to and then check if the operation is allowed.
If you have a View All feature, allowing a user to see all resources across projects, and a user can see resources in 3 of 5 projects, you need to ask your security model for a list of projects where the user has the View Resource privileged, and then add those projectIds to the query for loading the data. The projectIds needs to go into the query, just like sorting and pagination parameters. Typically you will need two queries since you also need a count query to calculate the total number of pages.
In my experience, the data model and the ACL are completely intertwined. If you want to make the ACL implementation independent of the data model, I fear you will either end up with an inefficient system that needs to load too much data and then filter away resources based on permissions afterwards. Or you will end up with a system that is overly complicated, because you need a generic way to transfer your ACL logic into the resource loading queries (and in the system I described, they are not simple to begin with).
There may be simpler systems than the one I described where a generic ACL implementation would work, but not on the enterprise stuff I have implemented over the last 8 years.
We have built a Spring MVC web application that is heavily relying on the user to do things in a certain order, and while it prevents users from circumventing this (without trying very hard) in the usual case (by not offering options to “go to places” you’re not supposed to at the given moment), we’re having some problems when people open another instance of the application in a new tab or browser window.
Since the application stores the domain model in the user’s session, using the program in another window can potentially mess up the model’s data, we’ve already implemented a page-ID mechanism that validates the user using the program in the correct order and not using the browser navigation, but we’re still facing problems when things like resetting the program (this is a feature, redirecting the user to the home screen and clearing the domain model) happen in one window and the user then tries to do something relying on the domain model to be filled with valid data in another window (leading to a NullPointerException quite quickly).
Storing some user details (like id, name, email) in a session might be ok, but storing the user's state (or any data that changes often and/or significantly affects other things in your app) doesn't sound like a good idea.
Hopefully one of the following approaches will fit you:
Don't save state in the session - load it from the database whenever you need it (in your case, whenever the user tries to access one of the steps that should be done in order). If you use caching, this shouldn't have major performance consequences.
Don't save state in the database, only in the session - works for limited cases (for instance, ordering airline tickets) where you can postpone committing your domain object until the process has finished.
Use Ajax for multi-step processes and don't save state at all (except implicitly in the browser). This requires putting all the steps into one page and ajaxifying some of your code.
Regardless, if someone logs in and tries to go to step 3, they shouldn't get an exception thrown at them, but that's a different story.
If I were you, I'd let user to wander around other parts of the website - the parts that don't interfere with your wizard process. However, once they try to restart it - check if there's PageID in session, and remind them they have not finished what they started, and ask if they would like to cancel/restart or continue on from where they left it.
In case anyone ever reads this question again:
Instead of the HttpSession keeping exactly one copy of the domain model it now holds a collection and we transport a reference to a single one of the models through the requests/responses so we can get the right model to work on in our controllers and views.
If I want to introduce the concept of blocked users, where is the most appropriate place to make the check if a user is blocked, without breaking the principles of good design?
Till now, I've been using Spring Security, to annotate the controller methods on whether a particular user has the permissions to do a certain action. With this blocked users thing, it gets a bit more complicated. Should I try to fit this again in the controller (possibly with Spring security again) or this is something which I should let the domain object decide itself?
I guess it'd be better to leave this on the controller leve, but I fear if my controllers won't turn into an if...else mess one day.
One approach could be to introduce role called "BLOCKED", assign it to all users when they are blocked and annotate all methods that do not allow blocked users to access them with:
#PreAuthorize("!hasRole('BLOCKED')")
public void secureMethod();
Another approach would be to store blocked status in user database or in some other storage. Then extend the UserDetailsService to return additional user information including the "blocked" flag. And the again use security EL to filter methods that do not allow blocked users to execute them:
#PreAuthorize("!principal.blocked")
public void secureMethod();
UPDATE:
Problem you mentioned in the comments can be approached in some similar way:
#PreAuthorize("!#photo.owner.blockedUsers.contains(principal.name)")
public void likePhoto(Photo photo);
For any more complex and/or generic rules I would advice to use AOP aspects to keep your code clean from too many ifs.
I have an application that is coded using Flex 3 on UI side and java # the service layer, along with BlazeDS. Now we need to authorize the users accessing the system based on the roles that are defined for them in the database, eg : say a user with role guest should not be able to access Admin tab on ui and also should not be able to do any operations other than viewing the data displayed on dashboard.Also the point to note here is that roles can be created dynamically by Super users from UI.
I came across this link which describes how to perform Role Based Authentication & Authorization
With this approach i need to define the roles in service-config.xml but since my roles are not pre-defined i cannot go with this.
Has anybody encountered a similar situation. Any pointers will be of great help.
Yes, I don't like the service-config idea either, don't blame you.
As far as the flex side, all you need to worry about is defining permissions, not roles or users of course.
Good form roles based security involves defining users, roles and permissions. You probably know this, but good to say it out loud anyway with the question.
Users are assigned one or more roles
Roles are assigned one or more permissions
Permissions secure functionality
So, in your application, you define specific permissions - pieces of the app that are dependent on security - visible / invisible / can or cant execute, etc. The way I normally do this is with a string constant. So, in an order management situation, I might have CanCreateOrder, CanViewOrder, CanCancelOrder, CanFlagOrder.
On the server side, a role will be tied to those permissions. Lets say:
Admin can do all
CustomerService can do view, and flag
Customer can do view
So on your server side, user A who is an admin, gets a list of all the permissions tied to the roles they are assigned, so the server sends back a string like this CanCreateOrder,CanViewOrder,CanCancelOrder,CanFlagOrder
Inside your application, when the user is authenticated and gets that list, its stored into a static global variable somewhere (or you .split() it into an array etc).
Then, when checking visibility or access to individual items, you simply check that array or string of values.
This offers a lot of flexibility as the items you are defining, most importantly, the permissions you're basically hard coding - are specific to the functional code they exist in. Therefore, there isn't a need to adjust them.
So, if you want to make customer service reps the ability to cancel orders later, you simply tie that permission to that role. Done. No code needs to be changed because the permission it simply tied to that functionality, not users, not roles.
I've done this in numerous applications, its a solid design. If you need permissions tied off other keys, that's a mildly different story, but this is a good starting point regardless.
Make sense?
**Naturally you may encrypt the security exchange and send over SSL, securing that transaction is out of scope of the discussion ;)