加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用Spring Security和CAS进行单点注销

发布时间:2020-12-15 01:25:01 所属栏目:大数据 来源:网络整理
导读:使用纯Spring Java Config我很难让Spring和CAS执行单点注销.我有单点登录使用下面的配置.我使用一个简单的JSP页面对url https://nginx.shane.com/app/logout执行表单POST,并在POSTd数据中包含CSRF值.这一切似乎都没有错误,但是当我进入安全页面时,它只是让我

使用纯Spring Java Config我很难让Spring和CAS执行单点注销.我有单点登录使用下面的配置.我使用一个简单的JSP页面对url https://nginx.shane.com/app/logout执行表单POST,并在POST’d数据中包含CSRF值.这一切似乎都没有错误,但是当我进入安全页面时,它只是让我回来而无需登录.有任何想法吗?

@Configuration
@EnableWebSecurity
public class SecurityWebAppConfig extends WebSecurityConfigurerAdapter {

@Bean
protected ServiceProperties serviceProperties() {
    ServiceProperties serviceProperties = new ServiceProperties();
    serviceProperties.setService("https://nginx.shane.com/app/j_spring_cas_security_check");
    serviceProperties.setSendRenew(false);
    return serviceProperties;
}

@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
    CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
    casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
    casAuthenticationProvider.setServiceProperties(serviceProperties());
    casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
    casAuthenticationProvider.setKey("an_id_for_this_auth_provider_only");
    return casAuthenticationProvider;
}

@Bean
public AuthenticationUserDetailsService

}

我还添加了一个WebListener来处理会话销毁事件:

@WebListener
public class SecurityWebListener implements HttpSessionListener {

private SingleSignOutHttpSessionListener listener = new SingleSignOutHttpSessionListener();

@Override
public void sessionCreated(HttpSessionEvent se) {
    listener.sessionCreated(se);
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    listener.sessionDestroyed(se);
}
}

这是日志输出

[org.springframework.security.web.FilterChainProxy] [/logout at position 6 of 14 in additional filter chain; firing Filter: 'LogoutFilter'] []
[org.springframework.security.web.util.matcher.AntPathRequestMatcher] [Checking match of request : '/logout'; against '/logout'] []
[org.springframework.security.web.authentication.logout.LogoutFilter] [Logging out user 'org.springframework.security.cas.authentication.CasAuthenticationToken@836ad34b: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffdaa08: RemoteIpAddress: 127.0.0.1; SessionId: FA880C15EF09C033E1CA0C8E4785905F; Granted Authorities: ROLE_ADMIN Assertion: org.jasig.cas.client.validation.AssertionImpl@fcd38ec Credentials (Service/Proxy Ticket): ST-23-1UandqRxBcG6HCTx0Pdd-cas01.example.org' and transferring to logout destination] []
[org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler] [Invalidating session: FA880C15EF09C033E1CA0C8E4785905F] []
[org.jasig.cas.client.session.HashMapBackedSessionMappingStorage] [Attempting to remove Session=[FA880C15EF09C033E1CA0C8E4785905F]] []
[org.jasig.cas.client.session.HashMapBackedSessionMappingStorage] [Found mapping for session.  Session Removed.] []
[org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler] [Using default Url: /] []
[org.springframework.security.web.DefaultRedirectStrategy] [Redirecting to '/app/'] []
最佳答案
(联合国)幸运我有类似问题;)当CAS试图调用您的应用程序注销时发生.一方面,CAS尝试传递sessionId以执行注销,另一方面,SpringSecurity期望获得CSRF令牌,该令牌不是由CAS发送的,因为它仅发送GET请求. CsrfFilter找不到csrf令牌并中断过滤器链.用户不知道这一点,因为CAS隐式调用了注销请求.请求直接从CAS服务器发送到应用程序服务器,而不是通过在Web浏览器中重定向用户.

为了使其工作,您需要配置HttpSecurity以排除/不包括LogoutFilter filterProcessesUrl(在您使用默认值时,在您的情况下为j_spring_security_logout).

假设您在尝试创建新管理员时要检查CSRF,为了解决问题,您需要按如下方式对其进行配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilter(casAuthenticationFilter());
    http.addFilterBefore(requestLogoutFilter(),CasAuthenticationFilter.class);

    http.exceptionHandling()
        .authenticationEntryPoint(casAuthenticationEntryPoint());

    http.authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')");

    http.csrf()
        .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/admin/create"));

    http.logout()
        .addLogoutHandler(handler)
        .deleteCookies("remove")
        .invalidateHttpSession(true)
        .logoutUrl("/logout")
        .logoutSuccessUrl("/");
}

只是为了表明,我已经补充说

http.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher(“/ admin / create”));.

注意你不能使用match all pattern(/ admin / **),因为你可能想要调用一些get请求,CSRF过滤器会期望它们发送令牌.

由于在那里引入了跨站点请求伪造(CSRF)支持,因此Spring Security 3.2x之前不会出现此类问题.

希望这些帮助:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读