Worklight authentication: multiple realms - ibm-mobilefirst

Want to check that this approach is reasonable. At first sight it seems to work.
Scenario is that we have different classes of users, when validating their credentials we can determine their class. We plan to have a "Master" realm which manages authentication and some subsidiary realms that we use to control access to particular adapter procedures, for example a "Gold".
We can then protect procedureOrdinary() with realm Master and procedureSpecial() with realm Gold.
In the Master authenticating code (derived from the DoubleStepAdapter example) we can write
WL.Server.setActiveUser("Master", userIdentity);
if ( some criteria are met )
WL.Server.setActiveUser("Gold", userIdentity);
We never actually set up a challenge handler for the Gold realm, authentication to the realm is handled via the Master realm.
Any issues with this idea.

Technically - it will work. However big assumption here is that user will NEVER try to access a procedure protected by "gold" realm before authenticating. To overcome this problem I'd recommend following approach - you need to define login-function and logout-function for each realm. Make sure that all of your login-functions return same JSON piece (or use same login-function in all realms). This way it doesn't matter with realm triggered the authentication - you will always get a same piece of JSON as a challenge and your app knows how to process it.

Related

Handling authorization with IdentityServer4

I'm extremely confused on how to use a centralized IDP with both authentication and authorization. The architecture for my project was to be a single web API and one React client. I wanted to keep things structured out into microservices just to try something more modern, but I'm having major issues with the centralized identity, as many others have.
My goal is fairly simple. User logs in, selects a tenant from a list of tenants that they have access to, and then they are redirected to the client with roles and a "tid" or tenant id claim which is just the GUID of the selected company.
The Microsoft prescribed way to add identity in my scenario is IdentityServer, so I started with that. Everything was smooth sailing until I discovered the inner workings of the tokens. While some others have issues adding permissions, the authorization logic in my application is very simple and roles would suffice. While I would initially be fine with roles refreshing naturally via expiration, they must immediately update whenever my users select a different tenant to "log in" to. However, the problem is that I cannot refresh these claims when the user changes tenants without logging out. Essentially, I tried mixing authorization with authentication and hit a wall.
It seems like I have two options:
Obtain the authorization information from a separate provider, or even an endpoint on the identity server itself, like /user-info but for authorization information. This ends up adding a huge overhead, but the actual boilerplate for the server and for the client is minimal. This is similar to how the OSS version of PolicyServer does it, although I do not know how their paid implementation is. My main problem here is that both the client and resource (API) will need this information. How could I avoid N requests per interaction (where N is the number of resources/clients)?
Implement some sort of custom state and keep a store of users who need their JWTs refreshed. Check these and return some custom response to the caller, which then uses custom js client code to refresh the token on this response. This is a huge theory and, even if it is plausible, still introduces state and kind of invalidates the point of JWTs while requiring a large amount of custom code.
So, I apologize for the long post but this is really irking me. I do not NEED to use IdentityServer or JWTs, but I would like to at least have a React front-end. What options do I have for up-to-date tenancy selection and roles? Right when I was willing to give in and implement an authorization endpoint that returns fresh data, I realized I'd be calling it both at the API and client every request. Even with cached data, that's a lot of overhead just in pure http calls. Is there some alternative solution that would work here? Could I honestly just use a cookie with authorization information that is secure and updated only when necessary?
It becomes confusing when you want to use IdentityServer as-is for user authorization. Keep concerns seperated.
As commented by Dominick Baier:
Yes – we recommend to use IdentityServer for end-user authentication,
federation and API access control.
PolicyServer is our recommendation for user authorization.
Option 1 seems the recommended option. So if you decide to go for option 1:
The OSS version of the PolicyServer will suffice for handling the requests. But instead of using a json config file:
// this sets up the PolicyServer client library and policy provider
// - configuration is loaded from appsettings.json
services.AddPolicyServerClient(Configuration.GetSection("Policy"))
.AddAuthorizationPermissionPolicies();
get the information from an endpoint. Add caching to improve performance.
In order to allow centralized access, you can either create a seperate policy server or extend IdentityServer with user authorization endpoints. Use extension grants to access the user authorization endpoints, because you may want to distinguish between client and api.
The json configuration is local. The new endpoint will need it's own data store where it can read the user claims. In order to allow centralized information, add information about where the permissions can be used. Personally I use the scope to model the permissions, because both client and api know the scope.
Final step is to add admin UI or endpoints to maintain the user authorization.
I ended up using remote gRPC calls for the authorization. You can see more at https://github.com/Perustaja/PermissionServerDemo
I don't like to accept my own answer here but I think my solution and thoughts on it in the repository will be good for anyone thinking about possible solutions to handing stale JWT authorization information.

What's the expected behavior of a dependent app when an LDAP user's DN changes?

Is there any expected/standardized behavior for an app that authenticates via LDAP, when one of its registered users has its DN changed? (Or more generally, when their effective principal changes, which seems to commonly be their DN. I'll say "principal" instead from here, though I usually think "DN".)
Here's an example from Gitlab running into this issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/993
In their case (based on the commit linked in that issue) they seem to address this by using multiple attributes to identify users instead of a single one, so that a single change doesn't prevent them from mapping back to the same LDAP user.
It seems to me the available options would be:
Don't try to prevent the issue but provide some method to change the principal stored (either in-app or via DB modifications)
Try to prevent the issue by picking (automatically or manually by user) a better, static user attribute to use as principal
Try to mitigate the issue by cross-referencing multiple attributes, as in the above links
Which of these would be the expected/"best" approach here, if any?

Grails 3 and Spring Security - authenticate user in filter

I'm developing a Grails 3 web-app powered with Spring Security plugin, which already makes large use of #Secured annotations to protect controllers and actions according to the privileges of single logged-in users.
The login is currently managed via the usual username/password pair.
Now a new requirement came up, involving a custom request header, having as value a sort of 'authorization token':
this token identifies a group of users (let's call it team)
if this token is recognized as valid, matching against DB, then the whole application should behave as a predefined user (let's call it John, part of the team) was logged-in. In this sense it should act as a pre-authentication. This user will have his own roles, so the application will respond accordingly, as if John would had logged in with his own username/password.
if the token is not recognized, 401 status must be returned.
if the token is not passed, the application must have its current behavior, to the token management should be considered optional must not impact the current implementation at all.
I considered defining a custom filter (I also took a look at this post, which however has different requirements), but I cannot even determine:
the feasibility of this task
whether or not filters are the best approach (but I guess so as Interceptors are triggered too late, and I need some additional logic to be evaluated before Spring Security comes into play)
possibly, the best filter to extend
So any suggestion is welcome! Thanks in advance
Not an expert on this, but I would implement a custom UserDetailsService and set the authorities based on the token condition. You might also be able to do it in an AuthenticationSuccessListener.

Spring data REST & data security

So I have a nice set of Spring Data REST repositories and they work great. Now I want to secure the data they produce. The URLs to the repositories are secure, in that, only an authenticated user has authorization to call them. However, only data in the database associated to the user should be sent to the client.
I have implemented an interceptor which gets called prior to the repository call which contains information about the logged in user, but I'm not sure how I can ensure only data produced by the REST call is data associated to the logged in user.
Obviously the client is coded to only make calls with links associated to the currently logged in user, but a user could simply change the URL to look at data they are not supposed to see.
Has anyone solved this issue?
Thanks,
Cory.
If you're using spring security, you can insert additional filters (ideally, based upon the url, or domain object.)
If you want object level security, you can still do the same thing, but you're going to have to somehow specify who/what role is allowed to access which domain object/id combinations, in either case, I don't think spring data rest handles (or should handle) any of that.
Spring Security's #PostFilter allows you to filter collection or arrays on the basis of authorization.
#PostFilter ("filterObject.owner == authentication.name")
public List<Book> getBooks();
Check these documented examples
https://github.com/spring-projects/spring-data-examples/tree/master/rest/security

GWT: Authentication for some part of application using GWT login page

My application has some features that are accessible to all users, and some other features to which access should be restricted to authenticated users only. All these restricted features exists within some set of GWT Places, thus, all Places available in application can be divided into two groups: "accessible for all", and "restricted". In my opinion, places with restricted access, could implement some interface (let's say it would be RestrictedAccess), and if user proceeds to one of them, and it has not been authenticated yet, it will be redirected to the login screen - it's more OO-approach than applying filters basis on URL.
What I'm trying to achieve is:
Information about if user has been
authenticated or not should be
stored on server (it's not something
that could be stored in a cookie...)
Login page is a standard GWT place+view+activity (!)
User name & password validation is done on the server side.
So far, I've introduced RestrictedAccess interface, which is implemented by some set of places. My FilteredActivityMapper.Filter implementation, which is passed to the FilteredActivityMapper wrapping application activity mapper has the following logic:
Place filter(Place place) {
if (place instanceof RestrictedAccess && !userHasBeenAuthenticated()) {
return new LoginPlace();
}
// return the original place - user has been already authenticated or
// place is accesible for all users
return place;
}
private boolean userHasBeenAuthenticated() {
// remote call - how to do ???
}
The problem is with userHasBeenAuthenticated() method (user should not be redirected to the LoginPlace, if it has been already authenticated). If I want to store this information on the server-side, I have to do GWT RPC/request factory call here, but both are asynchronous, so I cannot work on its result in the filter method.
I know that I can use web.xml filters or some external framework (e.g. spring security), but none of this approach allows me to have login page as a standard GWT - based form, or indicating in the more OO way that access to some place should be restricted.
Thanks in advance for any hints
EDIT: I've started to wondering if places filtering (restricted/not restricted) should take place on the client side at all. If, as it was suggested, there is a possibility to hack code indicating if user has been authenticated or not, there is also possibility to hack places filtering code, so that it will be possible to access restricted places without signing in.
Piotrek,
I think there is a security issue with calling userHasBeenAuthenticated() - it would be possible to hack the client side code to return true every time this function is called.
The solution I've implemented is to simply return SC_UNAUTHORIZED if an unauthenticated user attempts to access any remote service. I've overridden the RequestFactory onResponseReceived function which redirects to a login page if the response is SC_UNAUTHORIZED. Idea taken from:
http://code.google.com/p/google-web-toolkit/source/browse/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthRequestTransport.java
This works for our situation where the Activities and Places are all data-centric - each place change retrieves data from the server. If a user isn't authenticated they simply don't get the data and get redirected to a login page.
I realize your situation is slightly different in that some places are accessible to everyone, in which case you could configure only the restricted services to return SC_UNAUTHORIZED.
I have a similar application with the same requirements. As yet I have not got round to to the implementation but I was thinking along the same lines.
What I was planning on doing is storing the authentication state client side in an AuthenticationManager class. When the app starts I was going to request the login info from the server (I was thinking of running on app engine so I would get the authentication state and also get the open id login/logout URLs) and store this in the AuthenticationManager. Acegi/Spring Security works in a simlar way so this info is available server side if you use those too.
When the user logs in/out they will be redirected by the server and the new state will be retrieved. This should keep the client authentication state in line with the server. Each RPC request on the server has to be checked for authentication too. I was using the gwt-dispacth library and this has some rudimentary authentication checking and cross site script protection in in too (although I think latest GWT has this for generic RPC).
One issue is session timeouts. Again the gwt-dispath library has some code that detects this and returns session expired exceptions to the client which can be intercepted and the auth manager updated.
Hope that makes some sense.