Как отобразить зарегистрированные данные пользователя на незащищенной странице JSP после входа через Spring Security и CAS? - PullRequest
1 голос
/ 25 ноября 2011

У меня есть простой пример веб-приложения.Некоторые незащищенные страницы и некоторые защищенные страницы.

Вход осуществляется через Spring Security и CAS.Приложение в основном работает нормально - пользователи перенаправляются на страницу входа в CAS при запросе защищенного ресурса, вход в систему работает, и пользователь перенаправляется обратно на защищенную страницу, которую он запрашивал.У пользователя будут различные свойства аутентификации - их можно будет проверить с помощью тега Spring Security: 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 во время сеанса.Сначала я подумал, что это сработает - на незащищенных страницах он будет заполнен данными «Предоставленные полномочия = ROLE_ADMIN».Итак, я подумал, что смогу использовать это, чтобы определить, вошел ли пользователь в систему и имеет ли он необходимые полномочия.Однако SPRING_SECURITY_CONTEXT не отображается на самой первой защищенной странице, которая загружается при возврате из CAS, - только при последующих загрузках страницы.

1 Ответ

0 голосов
/ 30 ноября 2011

Вы должны сообщить диспетчеру сеансов 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>

Надеюсь, это поможет и будет завершено.Я должен уйти сейчас, но если вам нужно больше, просто спросите

...