我正在使用基本身份验证并希望使会话无效(Spring Security)

时间:2017-09-07 10:31:24

标签: spring spring-security

这是ApplicationContext-security.xml 为其定义了默认的Spring注销过滤器 单击注销链接后不会使会话失效,即使在单击注销链接后,浏览器也会存储用户凭据

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
        xmlns:beans="http://www.springframework.org/schema/beans"
        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-4.3.xsd 
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security-4.2.xsd">
        <beans:import resource="classpath:odk-security-settings.xml"/>
        <beans:bean id="basicAuthenticationMessageDigestPasswordEncoder"
                class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
        <http use-expressions="true">
        </http>
        <filter-security-metadata-source id="securityPolicy" use-expressions="true">
            <intercept-url pattern="/logout.html" access="true" />
            <intercept-url pattern="/multimode_login.html" access="true" />
            <intercept-url pattern="/relogin.html" access="true" />
            <intercept-url pattern="/local_login.html" access="isFullyAuthenticated() and hasAuthority('AUTH_LOCAL')" />
            <intercept-url pattern="/www/**" access="hasRole('ROLE_USER')" />
            <intercept-url pattern="/roles/granted" access="isFullyAuthenticated() and hasRole('ROLE_USER')" />
            <intercept-url pattern="/odktables/*/tables/*/ref/*" access="hasRole('ROLE_SYNCHRONIZE_TABLES')" method="GET" />
        </filter-security-metadata-source>
        <beans:bean id="serverSpringSecurityFilterChain"
            class="org.springframework.security.web.FilterChainProxy">
            <beans:constructor-arg>
                <beans:list>
                    <beans:bean class="org.springframework.security.web.DefaultSecurityFilterChain">
                        <beans:constructor-arg>
                            <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                                <beans:constructor-arg type="java.lang.String" value="/local_login.html"/>
                            </beans:bean>
                        </beans:constructor-arg>
                        <beans:constructor-arg>
                            <beans:list>
                                <beans:ref bean="channelProcessingFilter"/>
                                <beans:ref bean="securityContextPersistenceFilter"/>
                                <beans:ref bean="logoutFilter"/>
                                <beans:ref bean="oauth2ResourceFilter"/>
                                <beans:ref bean="oobAuthFilter"/>
                                <beans:ref bean="${security.server.deviceAuthentication}AuthFilter"/>
                                <beans:ref bean="requestCacheAwareFilter"/>
                                <beans:ref bean="anonymousFilter"/>
                                <beans:ref bean="securityContextHolderAwareFilter"/>
                                <beans:ref bean="sessionManagerFilter"/>
                                <beans:ref bean="localExceptionTranslationFilter"/>
                                <beans:ref bean="filterSecurityInterceptor"/>
                            </beans:list>
                        </beans:constructor-arg>
                    </beans:bean>
                    <beans:bean class="org.springframework.security.web.DefaultSecurityFilterChain">
                        <beans:constructor-arg>
                            <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                                <beans:constructor-arg type="java.lang.String" value="/**"/>
                            </beans:bean>
                        </beans:constructor-arg>
                        <beans:constructor-arg>
                            <beans:list>
                                <beans:ref bean="channelProcessingFilter"/>
                                <beans:ref bean="securityContextPersistenceFilter"/>
                                <beans:ref bean="logoutFilter"/>
                                <beans:ref bean="oauth2ResourceFilter"/>
                                <beans:ref bean="oobAuthFilter"/>
                                <beans:ref bean="${security.server.deviceAuthentication}AuthFilter"/>
                                <beans:ref bean="requestCacheAwareFilter"/> 
                                <beans:ref bean="anonymousFilter"/>
                                <beans:ref bean="securityContextHolderAwareFilter"/>
                                <beans:ref bean="sessionManagerFilter"/>
                                <beans:ref bean="exceptionTranslationFilter"/>
                                <beans:ref bean="filterSecurityInterceptor"/>
                            </beans:list>
                        </beans:constructor-arg>
                    </beans:bean>
                </beans:list>
            </beans:constructor-arg>
        </beans:bean>
        <beans:bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
          <beans:property name="channelDecisionManager" ref="channelDecisionManager"/>
          <beans:property name="securityMetadataSource">
            <filter-security-metadata-source request-matcher="ant" use-expressions="false">
                <intercept-url pattern="/logout.html" access="${security.server.channelType}" />
                <intercept-url pattern="/multimode_login.html" access="${security.server.channelType}" />
                <intercept-url pattern="/relogin.html" access="${security.server.channelType}" />
                <intercept-url pattern="/ssl/**" access="${security.server.secureChannelType}"/>
                <intercept-url pattern="/local_login.html" access="${security.server.channelType}" />
                <intercept-url pattern="/**" access="${security.server.channelType}"/>
            </filter-security-metadata-source>
          </beans:property>
        </beans:bean>
        <beans:bean id="logoutFilter"
            class="org.springframework.security.web.authentication.logout.LogoutFilter">
            <beans:constructor-arg name="logoutSuccessUrl" value="/logout.html" />
            <beans:constructor-arg name="handlers">
                <beans:list>
                    <beans:bean
                        class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
                        <beans:property name="invalidateHttpSession" value="true"/>
                    </beans:bean>
                </beans:list>
            </beans:constructor-arg>
            <beans:property name="filterProcessesUrl" value="/j_spring_security_logout"/>
        </beans:bean>
        <beans:bean id="anonymousProvider"
            class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
            <beans:constructor-arg type="java.lang.String">
                <beans:bean id="sitePreferencesBean.siteKey" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
            </beans:constructor-arg>
        </beans:bean>
        <beans:bean id="basicAuthFilter"
            class="org.opendatakit.common.security.spring.BasicAuthenticationFilter">
            <beans:constructor-arg>
                <beans:bean class="org.springframework.security.authentication.ProviderManager">
                    <beans:constructor-arg>
                        <beans:list>
                            <beans:ref bean="basicAuthenticationProvider" />
                            <beans:ref bean="anonymousProvider" />
                        </beans:list>
                    </beans:constructor-arg>
                </beans:bean>
            </beans:constructor-arg>
            <beans:constructor-arg ref="basicEntryPoint" />
        </beans:bean>
        <beans:bean id="basicAuthenticationProvider"
            class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
            <beans:property name="passwordEncoder" ref="basicAuthenticationMessageDigestPasswordEncoder" />
            <beans:property name="saltSource">
                <beans:bean class="org.opendatakit.common.security.spring.AggregateUserSaltSource"/>
            </beans:property>
            <beans:property name="userDetailsService" ref="basicLoginService" />
        </beans:bean>
        <beans:bean id="basicLoginService"
            class="org.opendatakit.common.security.spring.UserDetailsServiceImpl">
            <beans:property name="datastore" ref="datastore"/>
            <beans:property name="userService" ref="user_service"/>
            <beans:property name="passwordType" value="BasicAuth"/>
            <beans:property name="credentialType" value="Username"/>
            <beans:property name="authorities">
                <beans:list>
                    <beans:bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
                        <beans:constructor-arg value="AUTH_LOCAL"/>
                    </beans:bean>
                </beans:list>
            </beans:property>
        </beans:bean>
    </beans:beans>

这是基于频道的配置 如果还有其他需要请告诉我

2 个答案:

答案 0 :(得分:1)

spring-security-logout-namespace正是为此而存在的。

  1. 退出网址

    <http>
            ...
            <logout logout-url="/logout"/> 
    
    </http>
    
  2. 使会话无效并删除Cookie

    <http>
        <logout
          logout-url="/logout"
          delete-cookies="JSESSIONID" />
    <http/>
    

答案 1 :(得分:1)

您可以编写自己的LogoutHandler,如果会话仍包含有效的身份验证,则该响应将以“ 401未经授权”响应。浏览器将显示HTTP基本授权对话框,用户可以在其中输入新凭据或单击“取消”按钮。

如果用户输入有效的凭据,则将登录。如果用户输入了错误的凭据,该对话框将再次出现。如果用户单击“取消”按钮,则处理程序中的Authentication对象将为null,并且响应可以将浏览器重定向到注销页面或没有索引等访问限制的页面。

处理程序

public class LogoutHandler extends SimpleUrlLogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                            Authentication authentication) throws IOException, 
    ServletException {
        if (authentication == null) {
            response.sendRedirect(request.getContextPath());
        } else {
            response.sendError(401);
        }
    }

}

WebSecurityConfigurerAdapter

private final LogoutHandler logoutHandler;

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
    ...
    .and().httpBasic()
    .and().logout()
    .logoutUrl("/logout")
    .logoutSuccessHandler(logoutHandler)
    .invalidateHttpSession(true)
    .deleteCookies("JSESSIONID")
    ...
}