如何通过Spring Security和CAS登录后在非安全的JSP页面上显示登录的用户详细信息?

时间:2011-11-25 14:28:23

标签: spring-security cas

我有一个简单的Web应用程序示例。一些不安全的页面和一些安全的页面。

登录是通过Spring Security和CAS进行的。应用程序主要工作正常 - 用户在请求安全资源时会被定向到CAS登录页面,登录工作,用户被重定向回他们请求的安全页面。用户将拥有各种身份验证属性 - 可以使用Spring Security taglib进行检查:http://www.springframework.org/security/tags - 例如:

Authentication class : 
    class   org.springframework.security.web.
    authentication.preauth.PreAuthenticatedAuthenticationToken

Authentication authorities : [ROLE_ADMIN]

Authentication name : admin-user

Authentication authenticated : true

Authentication principal : 
    org.springframework.security.core.userdetails.User@bf0d4bda:
    Username: admin-user; 
    Password: [PROTECTED]; 
    Enabled: true; 
    AccountNonExpired: true;   
    credentialsNonExpired: true; 
    AccountNonLocked: true; 
    Granted Authorities: ROLE_ADMIN

但是,一旦登录用户访问非安全页面,那么它们似乎被视为没有这些凭据。相反,它们被视为

Authentication class : class 
    org.springframework.security.authentication.AnonymousAuthenticationToken

Authentication authorities : [ROLE_ANONYMOUS]

Authentication name : anonymousUser

Authentication authenticated : true

Authentication principal : anonymousUser

因此,这使得无法使用安全标记库根据用户是否登录来显示或隐藏不安全页面上的页面项目 - 例如,如果用户已经登录,则无法显示注销按钮在:

<sec:authorize access="isAuthenticated()" >
    <a href='<c:url value="/j_spring_security_logout" />'>logout</a>
</sec:authorize>
如果没有登录,请

或显示登录按钮:

<sec:authorize access="not isAuthenticated()" >
    <a href='<c:url value="/secure/home" />'>login</a>
</sec:authorize>

登录用户即使在登录时也始终显示为未在这些页面中进行身份验证。因此,始终会看到登录按钮,而不会注销。回到安全页面时,没有问题。这对我的应用程序来说并不致命 - 但同样的原则使我无法使用仅适合登录用户的内容(菜单,消息等)自定义非安全页面。

这是Spring Security + CAS的正常行为吗?或者有没有办法让它像你期望的那样工作?也许我错误配置了过滤链?

还有一件事 - 我在会话中查看了SPRING_SECURITY_CONTEXT。起初我认为这会起作用 - 这会在不安全的页面上出现Granted Authorities = ROLE_ADMIN。所以,我想我可以用它来检测用户是否已登录并具有正确的权限。但是,SPRING_SECURITY_CONTEXT不会在从CAS返回时加载的第一个安全页面上弹出 - 仅在后续页面加载时。

1 个答案:

答案 0 :(得分:0)

你必须告诉Spring会话管理器实际上有一个用户会话,并且Spring必须维护它。

<http use-expressions="true"
    auto-config="true"
    lowercase-comparisons="true"
    disable-url-rewriting="true"
    access-denied-page="/accessDenied.jsf"
    entry-point-ref="casAuthenticationFilterEntryPoint">
    [..]
    <custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />
    <custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />

    <logout invalidate-session="true" 
        logout-success-url="${cas.url}/logout?service=${local.url}/workspace/" />
</http>

这是我们实施的安全过滤器链的一部分,重要的是下面定义的 concurrencyFilter casAuthenticationFilter

<beans:bean id="casAuthenticationFilter"
    class="org.springframework.security.cas.web.CasAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
    <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
    <beans:property name="sessionAuthenticationStrategy" ref="sas" />
</beans:bean>

<beans:bean id="sas"
    class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
    <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
    <beans:property name="migrateSessionAttributes" value="true" />
    <beans:property name="exceptionIfMaximumExceeded" value="true" />
    <beans:property name="alwaysCreateSession" value="true" />
    <beans:property name="maximumSessions" value="20" />
</beans:bean>

<beans:bean id="sessionRegistry"
    class="org.springframework.security.core.session.SessionRegistryImpl" />

<beans:bean id="concurrencyFilter"
    class="org.springframework.security.web.session.ConcurrentSessionFilter">
    <beans:property name="sessionRegistry" ref="sessionRegistry" />
    <beans:property name="expiredUrl" value="/sessionExpired.jsf" />
</beans:bean>

我希望有所帮助,并且完整。我现在要离开,但如果你需要更多,请问

相关问题