105 votes

Comment puis-je utiliser Spring Security sans sessions?

Je suis en création d'une application web avec Spring Security, qui sera en direct sur Amazon EC2 et l'utilisation d'Amazon Elastic Load Balancers. Malheureusement, ELB ne prend pas en charge les sessions persistantes, donc j'ai besoin de m'assurer que mon application fonctionne correctement sans sessions.

Jusqu'à présent, j'ai le programme d'installation RememberMeServices pour attribuer un jeton via un cookie, et cela fonctionne bien, mais je veux que le cookie expire à la session du navigateur (par exemple, lorsque le navigateur se ferme).

Je dois imaginer je ne suis pas le premier à vouloir utiliser le Printemps de Sécurité sans sessions... des suggestions?

130voto

Aldaviva Points 356

Dans Spring Security 3 avec Java Config , vous pouvez utiliser HttpSecurity.sessionManagement () :

 @Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
 

28voto

Jarrod Carlson Points 364

Cela semble être encore plus facile avec Spring Securitiy 3.0. Si vous utilisez la configuration d'espaces de noms, vous pouvez simplement procéder comme suit:

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

Ou vous pouvez configurer l'SecurityContextRepository comme nulle, et rien ne serait jamais sauvé de cette façon aussi .

27voto

Basri Kahveci Points 181

Nous avons travaillé sur le même sujet (l'injection d'un personnalisé SecurityContextRepository à SecurityContextPersistenceFilter) pendant 4 à 5 heures aujourd'hui. Enfin, nous avons pensé à elle. Tout d'abord, dans la section 8.3 du Printemps de Sécurité réf. doc, il y a un SecurityContextPersistenceFilter bean définition

<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
    <property name='securityContextRepository'>
        <bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
            <property name='allowSessionCreation' value='false' />
        </bean>
    </property>
</bean>

Et après cette définition, il y a cette explication: "Sinon, vous pouvez fournir une valeur null à la mise en œuvre de la SecurityContextRepository de l'interface, ce qui empêchera le contexte de sécurité d'être stocké, même si une session a déjà été créé lors de la demande."

Nous avons besoin d'injecter de notre coutume SecurityContextRepository dans le SecurityContextPersistenceFilter. Nous avons simplement changé le haricot définition ci-dessus avec notre impl personnalisé et de le placer dans le contexte de sécurité.

Lors de l'exécution de l'application, nous avons retracé les journaux et vu que SecurityContextPersistenceFilter n'était pas à l'aide de notre impl personnalisé, il a été à l'aide de la HttpSessionSecurityContextRepository.

Après quelques autres choses que nous avons essayé, nous avons compris que nous devions donner notre coutume SecurityContextRepository impl avec la "sécurité-contexte-référentiel-ref" attribut de "http" de l'espace de noms. Si vous utilisez le "http" de l'espace de noms et voulez injecter votre propre SecurityContextRepository impl, essayez de "sécurité-contexte-référentiel-ref" attribut.

Lorsque le "http" de l'espace de noms est utilisé, une salle de SecurityContextPersistenceFilter définition est ignoré. Comme je l'ai copié ci-dessus, le document de référence. ne pas l'indiquer.

Veuillez me corriger si j'ai mal compris les choses.

11voto

Lukas Herman Points 156

Jetez un coup d'œil à SecurityContextPersistenceFilter class. Il définit comment SecurityContextHolder est rempli. Par défaut, il utilise HttpSessionSecurityContextRepository pour stocker le contexte de sécurité dans une session http.

J'ai implémenté ce mécanisme assez facilement, avec la coutume SecurityContextRepository .

Voir les securityContext.xml ci-dessous:

 <?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>
 

8voto

hleinone Points 2367

En réalité, create-session="never" ne signifie pas être complètement apatride. Il existe un problème pour cela dans Spring Security management.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X