Java 如何从spring security获取当前登录的用户对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32052076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the current logged in user object from spring security?
提问by Leejoy
I am using Spring security version 3.1.4.RELEASE. How can I access the current logged in user object?
我正在使用 Spring 安全版本 3.1.4.RELEASE。如何访问当前登录的用户对象?
SecurityContextHolder.getContext().getAuthentication().getPrinciple()
returns user name, not user object. So how can I use the returned Username and get the UserDetails object?
返回用户名,而不是用户对象。那么如何使用返回的用户名并获取 UserDetails 对象呢?
I have tried the following code:
我尝试了以下代码:
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;
}
Following is the result:
结果如下:
[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 class as follows:
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 as follows:
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 class as follows:
UserDetails 类如下:
public class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> usersList;
public MyUserDetailsService() {
Collection<GrantedAuthority> authorityList;
final SimpleGrantedAuthority supervisorAuthority = new SimpleGrantedAuthority("supervisor");
final SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("user");
usersList = new TreeMap<String, UserDetails>();
authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(supervisorAuthority);
authorityList.add(userAuthority);
usersList.put("admin", new User("admin", "admin", authorityList));
authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(userAuthority);
usersList.put("peter", new User("peter", "password123", authorityList));
//probably don't use this in production
for(Map.Entry<String, UserDetails> 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);
}
}
回答by Serge Ballesta
You just went one step foo far. SecurityContextHolder.getContext().getAuthentication()
returns an Authentication
object. Youshould know how you authenticated the user, and what can the the concrete class implementing Authentication
. Assuming it is a subclass of AbstractAuthenticationToken
(all Spring provided implementation are), and getDetails()
returns a UserDetails
, you can just use:
你只是走了一步 foo 远。SecurityContextHolder.getContext().getAuthentication()
返回一个Authentication
对象。您应该知道如何对用户进行身份验证,以及实现Authentication
. 假设它是AbstractAuthenticationToken
(所有 Spring 提供的实现都是)的子类,并getDetails()
返回 a UserDetails
,您可以使用:
AbstractAuthenticationToken auth = (AbstractAuthenticationToken)
SecurityContextHolder.getContext().getAuthentication();
UserDetails details = (UserDetails) auth.getDetails();
回答by Bassem Reda Zohdy
you can use it like
你可以像这样使用它
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}
it is in spring security reference http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#obtaining-information-about-the-current-user
回答by sura2k
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Returns the current user object. This can be User
, UserDetails
or your custom userobject.
You will need to cast the return object to UserDetails
or your own user object if it is a custom one.
返回当前用户对象。这可以是User
,UserDetails
或者您的自定义用户对象。UserDetails
如果它是自定义对象,则需要将返回对象强制转换为或您自己的用户对象。
OR you can inject Authentication
or Principal
directly in to your controllers.
Principle is your UserDetails
/custom user object.
或者您可以注入Authentication
或Principal
直接注入您的控制器。原则是您的UserDetails
/custom 用户对象。
Note: UserDetails
is an interface
注:UserDetails
是一个接口
回答by Sam
You can simply inject the Authentication Interface to your Controller and get the username of the logged in user, like below:
您可以简单地将身份验证接口注入您的控制器并获取登录用户的用户名,如下所示:
@Controller
public class SomeController {
@GetMapping(value = "/username")
@ResponseBody
public String currentUserName(Authentication authentication) {
if (authentication != null) {
return authentication.getName();
} else {
return "";
}
}
}