当前位置: 首页 > 知识库问答 >
问题:

Spring SAML - 支持自定义 SAML 断言

金阳曜
2023-03-14

我们有一个产品有一个客户,当我们作为服务提供商并且idp在客户端时,我们使用Spring Security SAML为该客户实现了SAML流。

现在,我们有另一个客户也希望身份验证与 SAML 一起使用,并且我们希望同一 SP 为此客户实现 SAML 流,第二个客户还将有 2 个用于 SAML 的流,一个用于移动设备,另一个用于使用相同 IDP 的其他设备。两个客户的 IDP 是不同的。

问题

两个客户之间有一些差异,例如断言属性不同,成功身份验证的操作不同,目前我们提供自己的实现。

也可能有更多的变化,如不同的绑定等...

我的问题是,支持这种场景并能够扩展我的SP以支持更多SAML流的最佳选项/最佳实践是什么,断言属性和更多配置存在差异?

当我们使用Spring SAML时,我们应该为每种SAML风格使用不同的Spring Security上下文文件吗?

并行使用多个上下文时是否存在线程安全问题?

共有1个答案

周翰池
2023-03-14

我的问题是,支持这种场景并能够扩展我的SP以支持更多SAML流的最佳选项/最佳实践是什么,断言属性和更多配置存在差异?

为了分支某些配置,比如断言属性,您需要创建单独的服务提供者。其他配置和服务可以共享。其他配置应该共享。例如,我使用单个自定义SAMLUserDetailsService实现,它从凭证中提取唯一的EntityID,并使用它为每个IDP映射不同的SAML属性。

当我们使用Spring SAML时,我们是否应该为每种SAML风格使用不同的Spring Security上下文文件?并行使用多个上下文时是否存在线程安全问题?

我不建议单独运行多个安全上下文。根据我的经验,Spring SAML中涉及很多配置,并且很可能,您将不得不通过这种方式不必要地复制大量代码。

在Spring SAML中,有一个为不同的服务提供商使用不同别名的概念。我已经为许多IDP设置了许多服务提供商,并且能够使用一个Spring Security上下文并在需要处理差异的地方实现定制服务。我没有您的需求的完整列表,可能有一些在单个Spring Security上下文中根本无法完成,但我会等到确定情况属实后再采取这一路线。

每个IDP之间具体需要有什么不同?

我被允许发布的代码受到限制,但我已经包含了我能包含的内容。

> < li>

入口点URL -如果您的配置中有多个设置了别名的IDP,入口点URL默认为

"/saml/login/alias/"productAlias"? idp="entityId;

如果您在负载平衡器后面,您可以将其配置为将您想要的任何URL重写为客户的URL。

绑定和断言 - 这些绑定和断言在每个服务提供程序元数据.xml文件中配置,并且对于每个客户可以不同。真正的挑战是如何从经过身份验证的 SAML 请求中提取属性,并以可用形式获取它。

我不知道是否有更好的方法来做到这一点,但我的要求是让我配置的任何IDP都可以映射和配置任何绑定。为此,我实现了一个自定义的< code > SAMLUserDetailsService 。从传递给服务的< code>SAMLCredential中,您可以使用< code > credential . getremotentityid()来获取客户的映射。在那里,您需要从凭证中解析出属性。

解析Microsoft和其他IDP的SAML属性的示例

 public class AttributeMapperImpl implements AttributeMapper {

    @Override
    public Map<String, List<String>> parseSamlStatements(List<AttributeStatement> attributeList) {
        Map<String, List<String>> map = new HashMap<>();
        attributeList.stream().map((statement) -> parseSamlAttributes(statement.getAttributes())).forEach((list) -> {
            map.putAll(list);
        });
        return map;
    }

    @Override
    public Map<String, List<String>> parseSamlAttributes(List<Attribute> attributes) {
        Map<String, List<String>> map = new HashMap<>();
        attributes.stream().forEach((attribute) -> {
            List<String> sList = parseXMLObject(attribute.getAttributeValues());
            map.put(attribute.getName(), sList);
        });
        return map;
    }

    @Override
    public List<String> parseXMLObject(List<XMLObject> objs) {
        List<String> list = new ArrayList<>();

        objs.stream().forEach((obj) -> {
            if(obj instanceof org.opensaml.xml.schema.impl.XSStringImpl){
                XSStringImpl xs = (XSStringImpl) obj;
                list.add(xs.getValue());
            }else if(obj instanceof org.opensaml.xml.schema.impl.XSAnyImpl){
                XSAnyImpl xs = (XSAnyImpl) obj;
                list.add(xs.getTextContent());
            }
        });  

        return list;
    }

    @Override
    public String parseSamlStatementsToString(Map<String, List<String>> map) {
        String values = "";
        Iterator it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry) it.next();
            values += pair.getKey() + "=" + pair.getValue() + " ";
            it.remove(); // avoids a ConcurrentModificationException
        }
        return values;
    }

}
  • 对成功/失败采取行动-有许多可能的方法。我选择在控制器中使用一个endpoint,该endpoint可以访问所有请求成功后所进行的会话。成功认证后,我可以从会话中提取用户来自的IDP,并相应地重定向它们。失败有点困难,因为完全有可能并且可能有些失败会非常严重,以至于您不知道请求来自哪个IDP(即,如果saml消息使用错误的证书签名)
 类似资料:
  • 灵活配置每个管理员的功能权限和管理范围,各司其职更灵活。 【优化】为企业预置角色的同时,支持企业自定义角色 【新增】角色的管理范围支持自定义,分为部门或项目,单据或员工的管理 【新增】角色的功能权限支持自定义,允许不同角色所拥有的功能权限不同

  • 我的任务是通过Sustainsys(Kentor)库为我目前正在进行的项目设置SAML 2.0单点登录。这是我一直遵循的文档。该网站是一个webforms应用程序,因此我使用Sustainsys库的HTTPModule部分。我已将IDP(Okta)配置为将SAML2.0断言发送到文档中声明endpoint为/SAML或/SAML/Acs的网站。该网站是Kentico CMS网站,CMS提供了一个A

  • 问题内容: 我一直在尝试: 关于我的服务方式,但spring抱怨说: 我该如何解决? 问题答案: JPA不支持自定义隔离级别。你可以扩展类并覆盖与连接有关的方法,以便可以在 这是我写的但尚未测试的东西: 然后将其定义为你的属性

  • 我正在为一个开源会议写一个应用程序。 最初每个与会者将通过电子邮件或短信收到不同的链接,如 https://example.com/?token=FCCFC8BFA07643A1CA8015CBE74F5F17 然后用这个链接打开app,我们就可以通过令牌知道用户是哪个与会者。 Firebase在2016年发布了新的I/O动态链接功能,为用户提供了更好的体验。 我曾经尝试过,但是我找不到任何方法来

  • 我有一个使用spring security和mvc框架开发的门户应用程序。此门户应用程序连接到IDP(使用Spring security和Spring saml开发)进行身份验证。如果用户身份验证成功,用户将被导航到主页,其中为外部应用程序提供了多个链接……当用户单击应用程序链接时,用户应成功导航到相应的应用程序,而无需质疑登录页面。 其他应用程序是使用strut和Spring Security开

  • 问题内容: 我们正在使用注册自己的协议的软件。我们可以从浏览器运行应用程序,然后通过如下链接: 但是有没有办法检查用户系统是否支持这种自定义协议?如果不是,我们想请用户先安装软件。 例如: 编辑 我知道关于protocolLong属性,但是它仅在IE中有效。 问题答案: 不幸的是,没有简单的方法来实现这一目标。当然,没有预先确定是否安装协议处理程序的方法。 *正如您所提到的, *Internet