PreInvocationAdvice for authentication - java

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.

Related

REST API Creation of Multiple Resources

I am currently working with an API where a POST request may create multiple resources, depending on the resource being passed. To give you an example, I have a Reservation resource, and two child resources, Ancillary and SpecialRequest. A reservation is uniquely identified by an alphanumeric string of 6 characters, and an Ancillary is identified by a unique ID within the reservation (i.e. ancillary IDs are only known to the parent reservation).
So, to create an Ancillary, my API endpoint looks like this:
POST /reservations/{reservationId}/ancillaries/
Usually REST states that the resource being created (Ancillary in this case) is the resource that should be returned. However, my use-case is somewhat more complicated than that, since the reservation system which my API is interfacing with is legacy, and is somewhat unpredictable.
There are certain ancillaries (bundles) which actually create multiple ancillaries. For example, an ancillary might be a package of two other ancillaries, which costs less than if you had to purchase the other two ancillaries. Moreover, an ancillary might also be linked automatically to a SpecialRequest.
I'm wondering what my options are ... so far I've come up with the following:
Return the entire Reservation, which is sure to include all sub resources which were created and/or modified as a result of the Ancillary creation. This is the "safest" option, but in doing so I wouldn't be able to tell the user which Ancillarys were created.
Return only the Ancillary which was created, however this approach is likely make my API less usable since the API user is extremely likely to perform a GET /reservations/{reservationId}
Return a Ancillary[] regardless of the ancillary type, although this still leaves out the link between the Ancillary and the SpecialRequest.
Thanks in advance for your thoughts and input

Best approach to handle login and authorizations in Vaadin Flow?

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.

How do we effectively prevent concurrent use of a web-application in one session?

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.

Instance level access control in Apache Shiro

I found really a flexible security framework Apache Shiro. I successfully implemented authentication and authorization using Shiro.
One of appealing features of the framework is instance based security. I just copied example from Shiro website.
The following permissions are stored in the database.
printer:query:lp7200
printer:print:epsoncolor
The following code check if for a given printer instance, the current authenticated user has permission or not.
if ( SecurityUtils.getSubject().isPermitted("printer:query:lp7200") {
// Return the current jobs on printer lp7200
}
My question is that "Is this how permissions are stored in database?"
Is there a better way to store instance based permissions?
Please let me know.
Thanks
How you store this information is entirely up to you. Your Realm implementation is responsible for querying whatever datasource you're using and extracting permission data in the format you prefer.
Some people store them as strings directly (like those shown in your example), other people store them in a dedicated table (e.g. if using an RDBMS) (e.g. permission_type, target, action columns). You can associate the permission entities to roles or directly to users or to groups which are assigned to users, etc - however it makes sense for your application.
Your storage options are entirely up to you. You materialize the data however you wish to ensure the Realm.isPermitted(...) operations function as expected.
Instead of implementing the Realm.isPermitted(...) methods directly, many people find it more convenient to subclass the abstract AuthorizingRealm class and override the doGetAuthorizationInfo method and return AuthorizationInfo instances that support permission representations.
In that method, you could query your datastore, translate the data returned into AuthorizationInfo instances, and you'll be done (don't forget to enable authorization caching - you'll see a big performance benefit).
Overriding the Realm isPermitted methods is only necessary if you want very specific control over queries, etc.

Suggestions to implement Role based authorization for an existing application in Flex

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 ;)

Categories

Resources