如何使用jsf获取当前在Spring Security中登录的用户名?

时间:2014-06-10 15:42:19

标签: java spring jsf spring-security

我是Spring Security的新手。我正在使用jsf2和spring security 3.三个问题:

如何从会话组件访问当前登录用户的用户信息(名称,密码,角色,上次访问权限)?

为了在视图中使用它,例如根据用户的角色渲染元素。

如何知道用户是否已登录?如果用户未登录则在视图中显示“登录链接”,或者如果用户登录则显示“注销链接”。我必须在组件中使用Spring Security的哪个属性来存储此信息并在视图中使用它?

这是我的Authentification组件

@Scope("session")
@Component("Authentification")

public class Authentification {

String username;
public String loggedName() throws IOException,ServletException{
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if (principal instanceof UserDetails) {
      username = ((UserDetails)principal).getUsername();
    } else {
       username = principal.toString();
    }
    return username;
}

}

这个在我的xhtml文件中调用此方法:          一切正常,但当我尝试获取当前记录的用户名时,我有这个错误

Infos: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
juin 10, 2014 3:36:33 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
Grave: Error Rendering View[/boo/listProjets.xhtml]
javax.el.ELException: /boo/myDatatable.xhtml @286,68 value="#{Authentification.loggedName()}": Method not found: class $Proxy8.loggedName()
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
    at javax.faces.component.UIOutput.getValue(UIOutput.java:164)
    at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:75)
    at org.primefaces.component.outputlabel.OutputLabelRenderer.encodeEnd(OutputLabelRenderer.java:37)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:879)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1650)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1646)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:389)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:127)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:117)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:135)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:309)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:57)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

2 个答案:

答案 0 :(得分:1)

您可以编写自己的每个请求的拦截器,这些拦截器将放入模型和查看已登录用户的对象模型或匿名或其他任何内容。如果您总是需要在视图中获取已登录的用户,这是很好的方式,但如果您想立即获得它,一个控制器/页面 - 最好用具体方法来做。写方式是获取SecurityContext和调用方法getContext()。getAuthentication()。getPrincipal(),它为您提供了登录用户。您的代码不起作用,因为您尝试调用的方法不是静态的并且很好,因为这不是从查看中获取经过身份验证的用户的好方法。

我在地下,所以我无法添加一些代码片段。有。 获取登录用户的方法:

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

实现UserInterceptor的完整方法:

@Component
public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mav)
            throws Exception {
        if (mav != null) {
            SmartUserDetails user = (SmartUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            SmartUser smartUser = user.getSmartUser();
            mav.addObject("smartUser", smartUser);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e)
        throws Exception {

    }
}

我将登录用户转换为我的自定义模型。

答案 1 :(得分:0)

通过自定义界面获取用户。

要充分利用Spring依赖注入并能够在任何地方检索身份验证,而不仅仅是在@Controller bean中,您需要隐藏简单外观背后的静态访问:

public interface IAuthenticationFacade {
    Authentication getAuthentication();
}

@Component
public class AuthenticationFacade implements IAuthenticationFacade {

    @Override
    public Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }
}

Facade暴露Authentication对象,同时隐藏静态并保持代码解耦并完全可测试:

@Controller
public class SecurityController {

    @Autowired
    private IAuthenticationFacade authenticationFacade;

    public String currentUserNameSimple() {
        Authentication authentication = authenticationFacade.getAuthentication();
        return authentication.getName();
    }
}

如果您需要直接从jsf访问:

<label>#{authenticationFacade.authentication.name}</label>