Spring Security - 获取当前登录用户的详细信息
在Spring框架里面,可以通过以下几种方式获取到当前登录用户的详细信息:
1. 在Bean
中获取用户信息
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
String currentUserName = authentication.getName();
return currentUserName;
}
Spring Security
框架提供了多种AuthenticationToken
的派生类,根据自己的应用场景,可以对SecurityContextHolder
里面的AuthenticationToken
进行类型转换,如下:
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
//details里面可能存放了当前登录用户的详细信息,也可以通过cast后拿到
User userDetails = (User) authenticationToken.getDetails();
PS. AuthenticationToken
的类型转换同样适用于下面提到的Principal
类。
2. 在Controller
中获取用户信息
- 通过
Principal
参数获取:
import java.security.Principal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SecurityController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
- 通过
Authentication
参数获取:
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SecurityController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Authentication authentication) {
return authentication.getName();
}
}
- 通过
HttpServletRequest
获取
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SecurityController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
return principal.getName();
}
}
3. 通过Interface
获取用户信息
通过Interface
获取其实和第一种在Bean
中获取用户信息是一样的,都是访问SecurityContextHolder
获取的,只是进行了封装。
public interface IAuthenticationFacade {
Authentication getAuthentication();
}
@Component
public class AuthenticationFacade implements IAuthenticationFacade {
@Override
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
}
下面是使用方法:
@Controller
public class SecurityController {
@Autowired
private IAuthenticationFacade authenticationFacade;
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple() {
Authentication authentication = authenticationFacade.getAuthentication();
return authentication.getName();
}
}
4. 在JSP
页面中获取用户信息
要使用Spring Security
的标签特性,首先要在JSP
页面引入Security
的tag
:
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
通过以下方式可以获取到当前登录用户:
<security:authorize access="isAuthenticated()">
authenticated as <security:authentication property="principal.username" />
</security:authorize>
更多JSTL
的语法可以参考:https://docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/reference/pdf/spring-security-reference.pdf
注意这是Spring Security 5.0
的版本,其他版本可以从https://docs.spring.io/spring-security/site/docs/这里选择。