我有一个使用Spring Security的Spring MVC web应用程序。我想知道当前登录用户的用户名。我正在使用下面给出的代码片段。这是公认的方式吗?
我不喜欢在这个控制器中调用静态方法——恕我直言,这违背了Spring的全部目的。有没有一种方法来配置应用程序有当前的SecurityContext,或当前的认证,注入代替?
@RequestMapping(method = RequestMethod.GET)
public ModelAndView showResults(final HttpServletRequest request...) {
final String currentUser = SecurityContextHolder.getContext().getAuthentication().getName();
...
}
在Spring 3+中,您有以下选项。
方案一:
@RequestMapping(method = RequestMethod.GET)
public String currentUserNameByPrincipal(Principal principal) {
return principal.getName();
}
选择二:
@RequestMapping(method = RequestMethod.GET)
public String currentUserNameByAuthentication(Authentication authentication) {
return authentication.getName();
}
选项3:
@RequestMapping(method = RequestMethod.GET)
public String currentUserByHTTPRequest(HttpServletRequest request) {
return request.getUserPrincipal().getName();
}
选项4:花哨的一个:查看更多细节
public ModelAndView someRequestHandler(@ActiveUser User activeUser) {
...
}
我使用@Controller类中的@AuthenticationPrincipal注释以及@ controlleradvisor注释。例:
@ControllerAdvice
public class ControllerAdvicer
{
private static final Logger LOGGER = LoggerFactory.getLogger(ControllerAdvicer.class);
@ModelAttribute("userActive")
public UserActive currentUser(@AuthenticationPrincipal UserActive currentUser)
{
return currentUser;
}
}
其中UserActive是我用于已登录用户服务的类,并且扩展自org.springframework.security.core.userdetails.User。喜欢的东西:
public class UserActive extends org.springframework.security.core.userdetails.User
{
private final User user;
public UserActive(User user)
{
super(user.getUsername(), user.getPasswordHash(), user.getGrantedAuthorities());
this.user = user;
}
//More functions
}
真的很容易。