1

Java + Spring MVC + Hibernate + Spring Security 3.1 で webapp を開発しています。ログインページにリダイレクトする代わりにログアウトすると、セッション期限切れメソッドに移動するため、ログインページが表示されますが、「セッション期限切れ!」が表示されます。メッセージ...

ここに security-context.xml があります

<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <security:debug />

    <!-- preauthentication -->    
    <security:global-method-security pre-post-annotations="enabled">
    </security:global-method-security>

   <security:http auto-config="false" use-expressions="true" entry-point-ref="http403EntryPoint" access-denied-page="/errores/accesodenegado">
        <security:intercept-url pattern="/" access="permitAll"/>
        <security:intercept-url pattern="/error.jsp" access="permitAll"/>
        <!-- Allow non-secure access to static resources  -->
        <security:intercept-url pattern="/resources/**" access="permitAll"/>
        <security:intercept-url pattern="/autenticacion/**" access="permitAll"/>
        <security:intercept-url pattern="/errores/**" access="permitAll"/>
        <!-- URLs que dependen de perfiles -->
        <security:intercept-url pattern="/gestion/facturas/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONSL')"/>
        <security:intercept-url pattern="/gestion/tarifas/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONSL')"/>
        <security:intercept-url pattern="/gestion/envios/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')"/>
        <security:intercept-url pattern="/gestion/perfiles/**" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/gestion/usuarios/**" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/consulta/**" access="hasAnyRole('ROLE_CONSL','ROLE_ADMIN','ROLE_S_CEN')"/>
        <security:intercept-url pattern="/importacion/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')"/>
        <!-- Pantalla a la que redirige el logout -->           
        <security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
        <!-- El session timeout lleva a la pantalla de login -->
        <security:session-management invalid-session-url="/errores/sesionexpirada" />
    </security:http>

    <bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
    </bean>

    <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
        <security:filter-chain-map path-type="ant">
            <security:filter-chain pattern="/**" filters="j2eePreAuthFilter"/>
        </security:filter-chain-map>
    </bean>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref='preAuthenticatedAuthenticationProvider'/>
    </security:authentication-manager>

    <bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
    </bean>

    <bean id="preAuthenticatedUserDetailsService"
            class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService"/>


    <bean id="j2eePreAuthFilter" class="es.myApp.security.MyAppUserJ2eePreAuthenticatedProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
        <property name="continueFilterChainOnUnsuccessfulAuthentication" value="false"/>
    </bean>

    <bean id="authenticationDetailsSource" class="org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource">
        <property name="mappableRolesRetriever" ref="j2eeMappableRolesRetriever"/>
        <property name="userRoles2GrantedAuthoritiesMapper" ref="j2eeUserRoles2GrantedAuthoritiesMapper"/>
    </bean>

    <bean id="j2eeMappableRolesRetriever" class="org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever">
    </bean>

    <bean id="j2eeUserRoles2GrantedAuthoritiesMapper" class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
        <property name="attributePrefix" value="test"/>
    </bean>

</beans>

ログアウト ボタンは次を呼び出します。

@Controller
@RequestMapping("/autenticacion")
public class AutenticacionController {

[...]

@RequestMapping(value = "salir")
    public String salir(Model model, HttpServletRequest request, HttpServletResponse response) {        
//      request.getSession().removeAttribute(Constantes.USUARIO_SESION);
//      request.getSession().invalidate();
        return "redirect:/j_spring_security_logout";
    }
}

これらの行をコメントアウトして使用しようとしましたが、動作はまったく同じです... Constantes.USUARIO_SESION は、ユーザー変数の名前をセッションに格納します。

ログイン メソッドは、とりわけ以下を実行します。

request.getSession().setAttribute(Constantes.USUARIO_SESION, usuario);

UserDetails userDetails = myAppUserDetailsService.loadUserByUsername(usuario.getLogin());
Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                            SecurityContextHolder.getContext().setAuthentication(auth);

セッションの期限切れは次のようになります。

@RequestMapping("sesionexpirada")
    public String sesionExpirada(Model model, HttpServletRequest request, HttpServletResponse response) {
    MessageManager msgManager = new MessageManager();

    msgManager.addError("error.sesion.expirada");
    request.getSession().setAttribute("messageManager", msgManager);

    return "inicio";
}

そしてweb.xml

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Aplicación Web MyApp</display-name>

    <!-- Define la localización de los ficheros de configuración de Spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/classes/applicationContext.xml
        </param-value>
    </context-param>

    <!-- Reads request input using UTF-8 encoding -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>myAppUserJ2eePreAuthenticatedProcessingFilter</filter-name>
        <filter-class>es.myApp.security.XiscoUserJ2eePreAuthenticatedProcessingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>myAppUserJ2eePreAuthenticatedProcessingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Handles all requests into the application -->
    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>es.myApp.controller.XiscoDispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- del. welcome files -->
    <!-- useful for Servlet 3 container (Tomcat 7 and Jetty 6) -->
    <welcome-file-list>
        <welcome-file></welcome-file>
    </welcome-file-list>

    <!-- Página de error -->
    <error-page>
        <error-code>404</error-code>
        <location>/errores/error</location>
    </error-page>

    <!-- Tiempo de sesión -->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

    <listener>
        <listener-class>
          org.springframework.security.web.session.HttpSessionEventPublisher
        </listener-class>
    </listener>

    <!-- Referencia a recursos jndi WAS -->
    <resource-ref id="ResourceRef_MyApp>
        <res-ref-name>jdbc/myApp</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

</web-app>

Tomcat 6 と WAS 8.5 でテストしました...

編集:Spring Security のログアウトを取り除き、独自のログアウトを実装すると、期待どおりに動作します。

<security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>security-context.xml から消去し、ログアウト時に呼び出されるメソッドを変更します。

@RequestMapping("salir")
    public String salir(Model model, HttpServletRequest request, HttpServletResponse response) {        
        request.getSession().removeAttribute(Constantes.USUARIO_SESION);

        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        SecurityContextHolder.clearContext();

        return "inicio";
    }

なぜ今それが働いているのですか?これらのコード行は、Spring のログアウト コードから取られています...

4

2 に答える 2

1

追加する必要があります

 <security:session-management session-fixation-protection="none"/>

あなたsecurity:httpのセクションに。

于 2013-03-27T14:52:52.213 に答える
0

あなたが何を達成しようとしているのか理解できません。セッションを無効にし、Spring セキュリティ ログアウト URL にリダイレクトする独自のコントローラーを作成しました。コントローラーは不要です。Spring ログアウト URL を直接使用するだけで、デフォルトでセッションが無効になります。ログアウト時に特別な動作を追加する必要がある場合は、独自の LogoutSuccessHandler を作成するか、Spring ハンドラーの 1 つを拡張して LogoutFilter に追加します。

于 2012-09-25T15:28:07.143 に答える