This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Accessing session scoped objects

Mar 2nd, 2011, 08:18 PM

I am really stumped on how to do this. I've developed my app with Spring, RichFaces, and Hibernate. I first developed without security. Now, I'm trying to go back and lock down the app and I've hit a brick wall.

I've got security configured and am able to simulate a pre-authenticated user (ie. username is in the request header). Spring security finds the user name and correctly calls my UserDetailsService.loadUserByUsername.

There is where I start to experience my problem. I could load the roles of the username passed in, but the security scenario for this app is not that simple. According to 2 other data points (lets just call them 'Region'), the security for a user changes. For example, in Region 1, jdoe can do x, y, z. In Region2 jdoe can do a, b, c, z and so on.

I have the Region information in a User object that is in the Spring container stored in the 'session' scope.

My issue is I have no way to get a hold of that session scoped User object into my UserService implementation.

@Autowired
@Qualifier("myUser")
private User user;

This does not work because it does not appear that security can reference anything in the session scope.

Any suggestions would be GREATLY appreciated!! I am really under the gun now!

Comment

Thanks rwinch for your advice! I think using the SecurityContextHolder just might do it!

My plan is to load all of the GrantedAuthorities regardless of region for the users at initial entry to the site. There is no login here because it is using Oracle SSO (which I am treating like its Siteminder).

Once a user selects a region my theory is that I can obtain the principal, through SecurityContextHolder, which is of type UserDetails (which I have implemented to hold region) and then set the region. Once I have this information I can then have the correct authority returned rather then the entire set.

This may not be clear, but its my only hope right now.

Comments welcome!!

Comment

I am just about convinced that this can not be done. Once a user selects a different 'region' there is no way to pass this information on to the security layer and / or have the security layer re-establish (or retrieve) the new GrantedAuthorities.

Comment

I am just about convinced that this can not be done. Once a user selects a different 'region' there is no way to pass this information on to the security layer and / or have the security layer re-establish (or retrieve) the new GrantedAuthorities.

Shortcoming? Doesn't seem like this is that odd of a request.

I'm not sure why you would base permissions on something that you allow the user to change. If they discover this wouldn't they just change to the other region?

Typically the Authentication is immutable because there are threading considerations to take into account. You can either use synchronize or you can create a new Authentication and set it on the SecurityContextHolder when you need to change the value.

Comment

When a user is in a 'Region' they can only act on 'objects' in that region. They can't see any other objects unless they change to another 'Region'. They may not have permission to do all the things in Region A that they were allowed to do in Region B. If they choose not to change then they are limited to their currently selected region.

I'm just about to throw in the towel and look at another security layer or just wing it myself. I really don't want to have to do this.

Comment

I thought I was getting close. Since couldn't tell UserService.loadUserByUsername to add these 'region' parameters, I just filtered the results in a model class by looping thru and comparing them to the region data. The problem is I can't get those results back to where they belong inside of the security framework...at least I didn't think that I could.

Comment

When a user is in a 'Region' they can only act on 'objects' in that region. They can't see any other objects unless they change to another 'Region'. They may not have permission to do all the things in Region A that they were allowed to do in Region B. If they choose not to change then they are limited to their currently selected region.

Did I not understand your question correctly (I thought I answered it)? I guess I am not understanding your requirements. Lets assume I was currently in Region A but I was allowed to switch to Region B. Region B had a specific email in it that I wanted to view but I couldn't view it because I was in Region A. Why wouldn't I just switch to Region B and view it? If the user is allowed to be in Region A and B why require them to switch regions? Couldn't you just have all of their regions populated? Is this just too large of a value to be populated?

If you are doing very high level access control works well. Otherwise you will probably want to do permissions (the provided implementation in Spring Security is Acl's). You can try the contacts sample out. There is also a video on the Articles and Tutorials link that demonstrates some of the access control stuff.

Comment

I thought I was getting close. Since couldn't tell UserService.loadUserByUsername to add these 'region' parameters, I just filtered the results in a model class by looping thru and comparing them to the region data. The problem is I can't get those results back to where they belong inside of the security framework...at least I didn't think that I could.