Как я могу использовать безопасность Spring без сессий?

Я создаю веб-приложение с безопасностью Spring, которая будет жить на Amazon EC2 и использовать Эластичные Подсистемы балансировки нагрузки Amazon. К сожалению, ELB не поддерживает липкие сессии, таким образом, я должен удостовериться, что мое приложение работает правильно без сессий.

До сих пор я имею, устанавливают RememberMeServices для присвоения маркера через cookie, и это хорошо работает, но я хочу, чтобы cookie истек с сеансом браузера (например, когда браузер закрывается).

Я должен предположить, что я не первый, который захочет использовать безопасность Spring без сессий... какие-либо предложения?

93
задан Jarrod Carlson 24 March 2010 в 00:21
поделиться

4 ответа

В Spring Securitiy 3.0 это стало еще проще. Если вы используете конфигурацию пространства имен, вы можете просто сделать следующее:

<http create-session="never">
  <!-- config -->
</http>

Или вы можете настроить SecurityContextRepository как null, и ничто никогда не будет сохранено таким образом .

28
ответ дан 24 November 2019 в 06:16
поделиться

Небольшое примечание: это «create-session», а не «create-sessions»

create-session

Управляет энергией, с которой создается сеанс HTTP.

Если не установлен, по умолчанию используется «ifRequired». Другие варианты: « always »и« never ».

Установка этого атрибута влияет на свойства allowSessionCreation и forceEagerSessionCreation HttpSessionContextIntegrationFilter. allowSessionCreation всегда будет истинным, если для этого атрибута не установлено значение« never ». forceEagerSessionCreation имеет значение« false », если не установлено значение« always ».

Таким образом, конфигурация по умолчанию разрешает создание сеанса, но не заставляет его. Исключение составляет, если включено управление параллельным сеансом, когда forceEagerSessionCreation будет b e установлено значение true, независимо от того, какой здесь параметр. Использование «никогда» вызовет исключение во время инициализации HttpSessionContextIntegrationFilter.

Конкретные подробности использования сеанса можно найти в документации Javadoc HttpSessionSecurityContextRepository.

3
ответ дан 24 November 2019 в 06:16
поделиться

Взгляните на класс SecurityContextPersistenceFilter . Он определяет, как заполняется SecurityContextHolder . По умолчанию он использует HttpSessionSecurityContextRepository для хранения контекста безопасности в сеансе http.

Я довольно легко реализовал этот механизм с помощью специального SecurityContextRepository .

См. securityContext.xml ниже:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:sec="http://www.springframework.org/schema/security"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

    <context:annotation-config/>

    <sec:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"/>

    <bean id="securityContextRepository" class="com.project.server.security.TokenSecurityContextRepository"/>

    <bean id="securityContextFilter" class="com.project.server.security.TokenSecurityContextPersistenceFilter">
        <property name="repository" ref="securityContextRepository"/>
    </bean>

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg value="/login.jsp"/>
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
            </list>
        </constructor-arg>
    </bean>

    <bean id="formLoginFilter"
          class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationSuccessHandler">
            <bean class="com.project.server.security.TokenAuthenticationSuccessHandler">
                <property name="defaultTargetUrl" value="/index.html"/>
                <property name="passwordExpiredUrl" value="/changePassword.jsp"/>
                <property name="alwaysUseDefaultTargetUrl" value="true"/>
            </bean>
        </property>
        <property name="authenticationFailureHandler">
            <bean class="com.project.server.modules.security.CustomUrlAuthenticationFailureHandler">
                <property name="defaultFailureUrl" value="/login.jsp?failure=1"/>
            </bean>
        </property>
        <property name="filterProcessesUrl" value="/j_spring_security_check"/>
        <property name="allowSessionCreation" value="false"/>
    </bean>

    <bean id="servletApiFilter"
          class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>

    <bean id="anonFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
        <property name="key" value="ClientApplication"/>
        <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
    </bean>


    <bean id="exceptionTranslator" class="org.springframework.security.web.access.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint">
            <bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
                <property name="loginFormUrl" value="/login.jsp"/>
            </bean>
        </property>
        <property name="accessDeniedHandler">
            <bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
                <property name="errorPage" value="/login.jsp?failure=2"/>
            </bean>
        </property>
        <property name="requestCache">
            <bean id="nullRequestCache" class="org.springframework.security.web.savedrequest.NullRequestCache"/>
        </property>
    </bean>

    <alias name="filterChainProxy" alias="springSecurityFilterChain"/>

    <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map path-type="ant">
            <sec:filter-chain pattern="/**"
                              filters="securityContextFilter, logoutFilter, formLoginFilter,
                                        servletApiFilter, anonFilter, exceptionTranslator, filterSecurityInterceptor"/>
        </sec:filter-chain-map>
    </bean>

    <bean id="filterSecurityInterceptor"
          class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="securityMetadataSource">
            <sec:filter-security-metadata-source use-expressions="true">
                <sec:intercept-url pattern="/staticresources/**" access="permitAll"/>
                <sec:intercept-url pattern="/index.html*" access="hasRole('USER_ROLE')"/>
                <sec:intercept-url pattern="/rpc/*" access="hasRole('USER_ROLE')"/>
                <sec:intercept-url pattern="/**" access="permitAll"/>
            </sec:filter-security-metadata-source>
        </property>
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
    </bean>

    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter"/>
                <bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
            </list>
        </property>
    </bean>

    <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <property name="providers">
            <list>
                <bean name="authenticationProvider"
                      class="com.project.server.modules.security.oracle.StoredProcedureBasedAuthenticationProviderImpl">
                    <property name="dataSource" ref="serverDataSource"/>
                    <property name="userDetailsService" ref="userDetailsService"/>
                    <property name="auditLogin" value="true"/>
                    <property name="postAuthenticationChecks" ref="customPostAuthenticationChecks"/>
                </bean>
            </list>
        </property>
    </bean>

    <bean id="customPostAuthenticationChecks" class="com.project.server.modules.security.CustomPostAuthenticationChecks"/>

    <bean name="userDetailsService" class="com.project.server.modules.security.oracle.UserDetailsServiceImpl">
        <property name="dataSource" ref="serverDataSource"/>
    </bean>

</beans>
10
ответ дан 24 November 2019 в 06:16
поделиться

На самом деле create-session="never" не означает быть полностью stateless. Для этого есть проблема в управлении проблемами Spring Security.

8
ответ дан 24 November 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: