How to change principals of already logged in user programmatically? - java

Im using Java, CDI, JSF.
In my LoginModule implementation i authenticate user and in commit() method assigning user principals to Subject object.
Now, when user is logged in I would like to change its principals without re-logging and then show some other content/options - how can I do that? Is it possible?
I have tried to get current Subject object, it froced me to enable SecurityManager and provide security grants, otherwise Subject is null.
AccessControlContext acc = AccessController.getContext();
Subject thisSubject = Subject.getSubject(acc);
So first - i dont want to enable SecurityManager to get Subject object(am I really need it? maybe theres some kind of bypass?).
Second - how can I change principals programmatically when user is already logged in?
Thank you.

Related

Spring Security - How to change user roles dynamically?

I have a question about changing role dynamically in runtime. Suppose that we have a social network application (like Facebook) and we are using Spring security for authentication/authorization purpose.
When a person open his Homepage this person has the ADMIN role and can do everything with his Homepage. However, when he is visiting another friend's Homepage he should only have the role USER which can only do some restricted actions (he cannot delete posts in the Homepage of his friend, for example).
If we use AuthenticationManagerBuilder then we can only set one fixed role for each user.
Can anyone help me with this question?
Thank you.
I think you should overthink your concept. Users are always users.
Users with homepages are userWithHomepage
and real admins are admins.
You need to check on the page, whether the currentUser is privileged for the current page - and give him his roles on this site.
So "UserWithHomepage" comes to his own Homepage, you check: is this user privileged on this site? If yes: activate admin things on this site. If you add a role to his userContext, he could get access as this role to other sites, too. I think, this is a security flaw.
So simply set a marker on your controller or check each time, something happens (instantiation, button click etc.) if the user has the privilege to do so.
You shouldn't change your user roles based on what page they are visiting. In your case, when visiting the homepage, you should check if the user is the owner of the homepage, and if so, give him the option to edit/delete and if not, just don't give them the option (don't show the links for editing/deletion, throw an exception if they try to execute that request anyway).
Thanks all, actually checking if the user is the owner of the Homepage is exactly what we need to do!

Spring Security: Different authentication methods depending on entity

first post here, hope im doing right.
In a project, we have a scenario where we have a single web application with multiple entities. Currently, the login is managed via default JDBC Spring Security provider, working fine.
For a new requirement, we need that each entity can have their own login method (currently 2 methods would be available, the JDBC one, which is the current one, and the second method would be authentication via SAML, with each entity defining their own IdP, but this is another story)
I need some guidelines on how this can be achieved, I have done some search and I have found providers for different URL's, etc... But not different login methods for the same app and url's depending on the user type or entity.
Is a good approach to have a custom single entry point where we can check the entity user and then use the suitable authentication provider?
Kind regards,
Alex
As each of your users might be using a different IDP you will in any case need to determine the username before proceeding with initialization of the authentication process - but you already know this.
One approach to take (similar to what Microsoft is using with the Office 365 for corporate users) is:
display a login page with fields for standard username + password
once user enters username and blurs the input field, you make an AJAX call (to your custom API made for this purpose) and fetch information about authentication type + IDP to use for this user
in case the type is password you simply let user continue with filling in the password field and POST to the same place as you're used to for processing with the JDBC provider
in case the type is federated authentication you initialize authentication with the correct IDP by redirecting to /saml/login?idp=xyz and continue with the SAML flow
It's possible to avoid any APIs by submitting the form once user enters the username, or let user click a "Continue" button. It would then make sense to use a custom EntryPoint which:
redirects user to the main login page in case it wasn't provided with a username
displays either login page with username/password or redirects to the correct IDP, once username was provided

Spring Security allowing alternative to username

I'm using Spring security 3.x. In my login page, there is an additional field that the user would scan an ID card to populate. If they do this, the username is not required (it is looked up against the ID scanned), but the password still is.
The problem is that the username is required by my custom AuthenticationProvider. The ID is captured in a filter before this (UsernamePasswordAuthenticationFilter). I don't know how to connect them so my AuthProvider knows it doesn't require username (and also, how does it get the ID at this point since it is passed an Authentication object?).
You might need a special kind of Authentication interface that is not a UsernamePasswordAuthenticationToken and hence doesn't require the username and password both.
Then your AuthenticationProcessingFilter/AuthenticationProvider may create one of them.
Have a look at spring-cas-client and CasAuthenticationToken as an example.
The filter I was extending was FORM_LOGIN_FILTER, which is correct, however I needed to perform all the retrievals (j_username, j_password) here and call the authentication manager manually, instead of calling the super() method which passes the retrievals and auth manager calls to Spring. This also required extending the UsernamePasswordAuthenticationToken. Once I do this, they are connected.

Spring Security userCache invalidation

Using Spring Security I have a DaoAuthenticationProvider described like here:
http://static.springsource.org/spring-security/site/docs/2.0.x/reference/dao-provider.html
I also have caching (also like it's described in that article).
The problem is that when a request comes in with a good username (that is already in the cache), but a bad password - it returns the user from the cache as if it is a good username/password. Because it uses the username as the key, the password is not involved at all.
The exact code that returns the user from the cache:
UserDetails user = this.userCache.getUserFromCache(username);
Did anybody ever dealt with this problem before? I can also check if the password is the same, but it would be a custom thing.
Thank you.
If you configured your application with the standard components, the scenario should be as follows:
At user request arrival the Authentication object is created and populated with username and password supplied by user.
User details are retrieved: if it's possible, UserCache is used to retrieve previously cached user details (i.e. getUserFromCache is called either by implementations of UserDetailsService or AuthenticationProvider before the call to AuthenticationManager is performed). And it is 100% OK that the user details from cache will come with the good password.
After basic pre-authentication checks (credentials expiration etc.) the actual authentication occurs. At this point the password from cached user details is compared to the password stored in Authentication object supplied (which currently contains the wrong password). At this point authentication attempt fails.
However, if you implement your own AuthenticationProvider or AuthenticationManager, you are responsible for password checking.
What's the code that originally gets the user from the DB and caches it? Does it check the password? Sounds like you have an abstraction issue - Spring Security should not know where the user is coming from (DB or Cache) and should use the same logic either way.

Seam security with externally-orchestrated SSO

I have an application deployed on WebLogic 10.3.2 (11g), in which the user logs in through SSO. In other words, if the user is not logged in, he is redirected to SSO, where he logs in, and then is redirected back to the application. The whole redirection takes place by an the Oracle HTTP Server (a modified apache), which makes sure that only SSO-authenticated users can see the applciation.
So, when the user finally sees the application, he is already logged in.
Is there a way to use Seam security with this scenario? What I would like is to use the roles of the Subject to restrict access to certain pages and components.
A way I thought of, but for which I am not sure, is to use the subject that is populated by the SSO authentication provider of WebLogic, and use it to populate the Identity component of Seam. That would take place in the authentication method, which will always return true (since the user is already logged in). Inside the method, the credentials and roles of the Subject will be "transfered" inside the Seam identity.
Is this feasible at all?
Cheers!
You could write your own authenticate method, or override the Identity class and the login() method to achieve this. I've done something similar with a reverse proxy that performed our authentication. In the scenario, the proxy sent back the user ID of the authenticated user and all the groups they were a member of as header values. I wrote a filter to intercept the headers and then used my custom Identity class to do the rest.

Categories