我有一个使用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 Security ver >= 3.2,您可以使用@AuthenticationPrincipal注释:
@RequestMapping(method = RequestMethod.GET)
public ModelAndView showResults(@AuthenticationPrincipal CustomUser currentUser, HttpServletRequest request) {
String currentUsername = currentUser.getUsername();
// ...
}
这里,CustomUser是一个自定义对象,它实现了由自定义UserDetailsService返回的UserDetails。
更多信息可以在Spring Security参考文档的@AuthenticationPrincipal一章中找到。
在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) {
...
}
为了让它只显示在JSP页面中,你可以使用Spring Security标签库:
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/taglibs.html
要使用任何标记,必须在JSP中声明安全标记库:
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
然后在jsp页面中执行如下操作:
<security:authorize access="isAuthenticated()">
logged in as <security:authentication property="principal.username" />
</security:authorize>
<security:authorize access="! isAuthenticated()">
not logged in
</security:authorize>
注意:正如@SBerg413在评论中提到的,您需要添加
use-expressions = " true "
到security.xml配置中的“http”标签以使其工作。