ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-IDP上的Spring SAML预身份验证检查

2019-11-21 16:20:25  阅读:291  来源: 互联网

标签:spring-security saml spring-saml spring java


我正在基于Spring安全性和Spring Security SAML扩展(RC2)编写几个Web应用程序.

我有一种基本的方式来与多个服务提供者和一个身份提供者一起工作(基于spring saml docs中定义的示例).

当用户访问SP上的受保护资源时,他将被转发到IDP上的受保护资源.因此,由于用户尚未登录,因此将其重定向到登录页面(标准的spring安全性内容).登录后,将播放原始请求,并完成authNRequest / Response,并将用户重定向到原始受保护的资源.

我现在有一个要求,以确保所有服务提供者都必须在每次请求之前向身份提供者询问用户是否已登录(而不是在SP本地进行登录).

据我了解,在每次请求期间都会存储并查询本地(SP)和远程(IDP)安全上下文,如果没有有效的上下文,则将用户转发给身份提供者以进行身份​​验证过程.

所以我的问题是,有没有一种方法可以在SP端配置saml / spring安全性以始终“ ping”或要求IDP检查当前用户是否已登录,或者这种事情是否不必要/不受支持.

提前致谢

解决方法:

没错,Spring SAML在每个请求期间查询本地安全上下文,并在用户变为无效后将其转发给IDP.

定义上下文何时无效的典型机制是使用SAML属性SessionNotOnOrAfter.该属性包含在从IDP发送回的断言的AuthenticationStatement中.一旦时间超出SessionNotOnOrAfter中提供的值,Spring SAML将自动重新认证用户.

如果您想对每个请求重新进行身份验证,则可以例如添加一个类似于以下内容的新的自定义过滤器:

package fi.test;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class ReAuthenticateFilter extends GenericFilterBean {

    private static final String FILTER_APPLIED = "__spring_security_filterReAuthenticate_filterApplied";

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }

    protected void invoke(FilterInvocation fi) throws IOException, ServletException {

        if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)) {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } else {
            if (fi.getRequest() != null) {
                fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
            }
        }

       Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            if (authentication != null) {
                authentication.setAuthenticated(false);
            }
        }

    }

}

然后,您可以在Spring配置中包括过滤器:

<security:http entry-point-ref="samlEntryPoint">
    <security:custom-filter after="SECURITY_CONTEXT_FILTER" ref="reAuthenticateFilter"/>
    ...
</security:http>

<bean id="reAuthenticateFilter" class="fi.test.ReAuthenticateFilter"/>

对每个请求进行重新认证是相当昂贵的操作(通过用户浏览器往返IDP),并且很可能导致应用程序的响应速度较慢.

标签:spring-security,saml,spring-saml,spring,java
来源: https://codeday.me/bug/20191121/2052864.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有