如何从spring security获取当前登录的用户对象?

我使用的是Spring安全版3.1.4.RELEASE。 如何访问当前登录的用户对象?

SecurityContextHolder.getContext().getAuthentication().getPrinciple() 

返回用户名,而不是用户对象。 那么如何使用返回的用户名并获取UserDetails对象?

我试过以下代码:

 public UserDetails getLoggedInUser(){ final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) { if(auth.getDetails() !=null) System.out.println(auth.getDetails().getClass()); if( auth.getDetails() instanceof UserDetails) { System.out.println("UserDetails"); } else { System.out.println("!UserDetails"); } } return null; } 

以下是结果:

 [2015-08-17 19:44:46.738] INFO http-bio-8443-exec-423 System.out class org.springframework.security.web.authentication.WebAuthenticationDetails [2015-08-17 19:44:46.738] INFO http-bio-8443-exec-423 System.out !UserDetails 

AuthenticationFilter类如下:

 public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username"; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password"; public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME"; private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; private boolean postOnly = true; public CustomUsernamePasswordAuthenticationFilter() { super("/j_spring_security_check"); } public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); if(this.getAuthenticationManager()==null){ logger.info("Authentication manager is null."); } else { logger.info("Authentication manager was "+this.getAuthenticationManager().getClass().getName()); } return this.getAuthenticationManager().authenticate(authRequest); } protected String obtainPassword(HttpServletRequest request) { return request.getParameter(passwordParameter); } protected String obtainUsername(HttpServletRequest request) { return request.getParameter(usernameParameter); } protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); } public void setUsernameParameter(String usernameParameter) { this.usernameParameter = usernameParameter; } public void setPasswordParameter(String passwordParameter) { this.passwordParameter = passwordParameter; } public void setPostOnly(boolean postOnly) { this.postOnly = postOnly; } public final String getUsernameParameter() { return usernameParameter; } public final String getPasswordParameter() { return passwordParameter; } } 

AuthenticationProvider如下:

 @Component public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { private MyUserDetailsService userDetailsService; public MyUserDetailsService getUserDetailsService() { return userDetailsService; } public void setUserDetailsService(MyUserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } @Override protected void additionalAuthenticationChecks(UserDetails arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException { } @Override protected UserDetails retrieveUser(String arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException { return userDetailsService.loadUserByUsername(arg0); } } 

UserDetails类如下:

  public class MyUserDetailsService implements UserDetailsService { private final Map usersList; public MyUserDetailsService() { Collection authorityList; final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority("supervisor"); final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("user"); usersList = new TreeMap(); authorityList = new ArrayList(); authorityList.add(supervisorAuthority); authorityList.add(userAuthority); usersList.put("admin", new User("admin", "admin", authorityList)); authorityList = new ArrayList(); authorityList.add(userAuthority); usersList.put("peter", new User("peter", "password123", authorityList)); //probably don't use this in production for(Map.Entry user : usersList.entrySet()){ logger.info(user.getValue().toString()); } } @Override public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException { UserDetails ud = usersList.get(username); if (ud != null) { logger.info("loadUserByUsername: found match, returning " + ud.getUsername() + ":" + ud.getPassword() + ":" + ud.getAuthorities().toString()); return new User(ud.getUsername(), ud.getPassword(), ud.getAuthorities()); } logger.info("loadUserByUsername: did not find match, throwing UsernameNotFoundException"); throw new UsernameNotFoundException(username); } } 

 SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 

返回当前用户对象。 这可以是UserUserDetails或您的自定义用户对象。 您需要将返回对象UserDetailsUserDetails或您自己的用户对象(如果它是自定义用户对象)。

或者您可以将AuthenticationPrincipal直接注入控制器。 原则是您的UserDetails /自定义用户对象。

注意: UserDetails是一个界面

你可以像使用它一样

 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); } 

它是在春季安全参考http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#obtaining-information-about-the-current-user

你走了一步远。 SecurityContextHolder.getContext().getAuthentication()返回一个Authentication对象。 应该知道如何对用户进行身份validation,以及实现Authentication的具体类可以是什么。 假设它是AbstractAuthenticationToken的子类(所有Spring提供的实现都是),并且getDetails()返回UserDetails ,您可以使用:

 AbstractAuthenticationToken auth = (AbstractAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); UserDetails details = (UserDetails) auth.getDetails();