This is a Spring Security question.
In my application, I have a User entity as a domain object. This object contains implementation to support Spring UserDetails object. The authentication (login/logout) process works fine.
The challenge is that I need to extract that object from the session to make 'business logic' decisions in my code.
I've been reading about querying SecurityContextHolder, but frankly, I still don't know what is the best approach, given that multiple Spring versions seem to be a factor in those discussions. Also, the Principal object isn't a solution for me, as it does not seem to contain any access level or role information.
Below is a simple controller to illustrate my challenge. It has my User domain object hardcoded. I need to replace that block with code that will obtain the User object from Spring Security session. I'm looking for the best way to do this within Spring 3.
- Can I get this object as my domain object or do I need to get it as Spring UserDetails object and manually convert it?
Can this Security context lookup be injected somehow into my controller?
public class HomeController { @RequestMapping(value="/home.html", method=RequestMethod.GET) public ModelAndView getHomePage(Map<String, Object> model) { // Get current user User currentUser=new User(); currentUser.setUserName("Admin"); currentUser.setAccessLevel(UserAccessLevel.ADMINISTRATOR); // Construct HomePage bean HomeBean bean=new HomeBean(); bean.setCurrentUserName(currentUser.getUserName()); // Construct list of catalogs Collection<String> catalogList=new ArrayList<String>(); catalogList.add("articles"); catalogList.add("files"); catalogList.add("comments"); if(currentUser.hasAdministratorAccessLevel()) { catalogList.add("users"); } bean.setCatalogList(catalogList); // Construct and return ModelAndView ModelAndView mav=new ModelAndView(); mav.setViewName(WebView.HOME_PAGE.getViewName()); mav.addObject(bean.getBeanId(), bean); return mav; }
=== Update 2012-01-07 ======================================================
I'm working with Luke's suggestion. The method that gets UserDetails from session and converts it to a returned my domain User object is in my UserService.
Here's my controller:
@Controller
public class HomeController {
@Autowired
private UserService userService;
@RequestMapping(value="/home.html", method=RequestMethod.GET)
public ModelAndView getHomePage(Map<String, Object> model) {
// Construct HomePage bean
HomeBean bean=new HomeBean();
User currentUser=userService.getCurrentlyAuthenticatedUser();
bean.setCurrentUserName(currentUser.getUserName());
And here's key code from UserServiceImpl.getCurrentlyAuthenticatedUser():
@Override
public User getCurrentlyAuthenticatedUser() {
User currentUser=new User();
Authentication a = SecurityContextHolder.getContext().getAuthentication();
UserDetails currentUserDetails = (UserDetails) a.getPrincipal();
if(currentUserDetails==null) {
return currentUser;
}
currentUser.setUserName(currentUserDetails.getUsername());
This works but am I doing this right? Feedback much appreciated. I am still unable to retrieve my User domain object from the session. I'm retrieving Spring's UserDetails object and with it constructing my domain User object but in the process some information is lost.