总览

最新版本的WSO2 Identity Server(版本5.0.0)配备了“应用程序身份验证框架”,该框架提供了很大的灵活性,可以对来自使用异构协议的各种服务提供商的用户进行身份验证。 它具有多个扩展点,可用于满足企业系统中常见的几个自定义要求。 在这篇文章中,我将分享使用这样一个扩展点的细节。

功能扩展

在企业系统中使用SAML单一登录时,依赖方通过SAML响应来了解用户是否已通过身份验证。 在这一点上,依赖方尚不知道其为业务和授权目的可能需要的已认证用户的其他属性。 为了向依赖方提供这些属性详细信息,SAML规范允许在SAML响应中也发送属性。 WSO2 Identity Server通过为管理员提供的GUI开箱即用地支持此功能。 有关此功能和配置的详细信息,请参阅[1]。

当我们需要向SAML响应中添加除下划线用户存储中可用的属性之外的其他属性时,此特定扩展提供的灵活性会派上用场。 为了提供依赖方请求的所有属性,可能需要寻找外部数据源。

在这里我要描述的样本中,我们将研究一个场景,该系统需要提供一些存储在用户存储中的用户本地属性,以及一些我希望从外部数据源中检索到的其他属性。
遵循SAML响应是我们需要从WSO2 IS发送给依赖方的内容。

<saml2p:Response Destination="https://localhost:9444/acs" ID="faibaccbcepemkackalbbjkihlegenhhigcdjbjk"InResponseTo="kbedjkocfjdaaadgmjeipbegnclbelfffbpbophe" IssueInstant="2014-07-17T13:15:05.032Z"Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">localhost</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">..........</ds:Signature><saml2p:Status><saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></saml2p:Status><saml2:Assertion ID="phmbbieedpcfdhcignelnepkemobepgaaipbjjdk" IssueInstant="2014-07-17T13:15:05.032Z" Version="2.0"xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">.........</ds:Signature><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">Administrator</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData InResponseTo="kbedjkocfjdaaadgmjeipbegnclbelfffbpbophe"NotOnOrAfter="2014-07-17T13:20:05.032Z"Recipient="https://localhost:9444/acs"/></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2014-07-17T13:15:05.032Z" NotOnOrAfter="2014-07-17T13:20:05.032Z"><saml2:AudienceRestriction><saml2:Audience>carbonServer2</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2014-07-17T13:15:05.033Z"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement><saml2:Attribute Name="http://wso2.org/claims/role"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Internal/carbonServer2,Internal/everyone</saml2:AttributeValue></saml2:Attribute><saml2:AttributeStatement><saml2:Attribute Name="http://pushpalanka.org/claims/keplerNumber"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">E90836W19881010</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="http://pushpalanka.org/claims/status"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">active</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:AttributeStatement></saml2:Assertion>
</saml2p:Response>

在此响应中,我们具有一个本地属性(即角色)和另外两个属性http://pushpalanka.org/claims/keplerNumber和http://pushpalanka.org/claims/status,这些属性已从其他方法中检索出在我们的扩展名中定义。

怎么样?

  1. 实施定制逻辑以获取外部声明。 我们仅需注意两个事实。

    • 定制实现应实现接口“ org.wso2.carbon.identity.application.authentication.framework.handler.claims.ClaimHandler”,或扩展接口“ org.wso2.carbon.identity.application.authentication”的默认实现。 framework.handler.claims.impl.DefaultClaimHandler”。
    • 在方法“ public Map <String,String> handleClaimMappings”处返回的映射应包含我们要添加到SAML响应中的所有属性。

    以下是我按照上面编写的示例代码。 外部声明可能已从数据库中查询,从文件中读取或根据需要使用任何其他机制。

    public class CustomClaimHandler implements ClaimHandler {private static Log log = LogFactory.getLog(CustomClaimHandler.class);private static volatile CustomClaimHandler instance;private String connectionURL = null;private String userName = null;private String password = null;private String jdbcDriver = null;private String sql = null;public static CustomClaimHandler getInstance() {if (instance == null) {synchronized (CustomClaimHandler.class) {if (instance == null) {instance = new CustomClaimHandler();}}}return instance;}public Map<String, String> handleClaimMappings(StepConfig stepConfig,AuthenticationContext context, Map<String, String> remoteAttributes,boolean isFederatedClaims) throws FrameworkException {String authenticatedUser = null;if (stepConfig != null) {//calling from StepBasedSequenceHandlerauthenticatedUser = stepConfig.getAuthenticatedUser();} else {//calling from RequestPathBasedSequenceHandlerauthenticatedUser = context.getSequenceConfig().getAuthenticatedUser();}Map<String, String> claims = handleLocalClaims(authenticatedUser, context);claims.putAll(handleExternalClaims(authenticatedUser));return claims;}/*** @param context* @return* @throws FrameworkException*/protected Map<String, String> handleLocalClaims(String authenticatedUser,AuthenticationContext context) throws FrameworkException {....}private Map<String, String> getFilteredAttributes(Map<String, String> allAttributes,Map<String, String> requestedClaimMappings, boolean isStandardDialect) {....}protected String getDialectUri(String clientType, boolean claimMappingDefined) {....}/*** Added method to retrieve claims from external sources. This results will be merged to the local claims when* returning final claim list, to be added to the SAML response, that is sent back to the SP.** @param authenticatedUser : The user for whom we require claim values* @return*/private Map<String, String> handleExternalClaims(String authenticatedUser) throws FrameworkException {Map<String, String> externalClaims = new HashMap<String, String>();externalClaims.put("http://pushpalanka.org/claims/keplerNumber","E90836W19881010");externalClaims.put("http://pushpalanka.org/claims/status","active");return externalClaims;}
    }
  2. 将已编译的OSGI软件包放在IS_HOME / repository / components / dropins中。 (我们将其开发为OSGI捆绑软件,因为我们还需要使用RealmService获得本地声明。 您可以在此处找到完整的捆绑软件和源代码 )
  3. 使WSO2 Identity Server使用我们拥有的新的自定义实现。

在IS_HOME / repository / conf / security / applicationauthentication.xml中,配置新的处理程序名称。 (在“ ApplicationAuthentication.Extensions.ClaimHandler”元素中。)

   <ClaimHandler>com.wso2.sample.claim.handler.CustomClaimHandler</ClaimHandler>

现在,如果查看生成的SAML响应,我们将看到添加的外部属性。

干杯!

[1] – https://docs.wso2.com/display/IS500/Adding+a+Service+Provider

翻译自: https://www.javacodegeeks.com/2014/08/adding-custom-claims-to-the-saml-response-how-to-write-a-custom-claim-handler-for-wso2-identity-server.html

向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...相关推荐

  1. saml2_向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...

    saml2 总览 最新版本的WSO2 Identity Server(版本5.0.0)配备了"应用程序身份验证框架",该框架提供了很大的灵活性,可以对使用异构协议的各种服务提供商的 ...

  2. 如何编写 TypeScript 声明文件

    1. 什么是 TS 声明文件 在 TypeScript 中以 .d.ts 为后缀的文件,称为 TypeScript 声明文件.它的作用是描述 JavaScript 模块内所有导出接口的类型信息. 2. ...

  3. 蓝牙芯片----BK3431开发笔记------RW stack中添加自定义服务教程(4)

    一.实现自定义服务 在 RW 协议栈协议栈中添加一个自定义服务需要实现 6 个文件,分别为: custom.c custom.h custom_task.c custom_task.h app_cus ...

  4. java saml_java – 验证SAML响应的签名

    这是我的工作流程:我收到了SAML响应.我摆脱了签名信封,我将其标准化,检查摘要然后检查签名.我能够成功计算转换后的SAML响应的SHA1摘要并验证它.但是,RSA-SHA1签名检查仍然无法解决. 我 ...

  5. 向DataTable中添加自定义的行

    [标题]向DataTable中添加自定义行 [内容] 向DataTable中添加自定义行,然后绑定到DropDownList控件中,并且默认行为控件的第一行 如果表结构如下:              ...

  6. html怎样添加日历控件,向日历控件中添加自定义内容

    向日历控件中添加自定义内容 String[][] holidays; void Page_Load(Object Sender, EventArgs e) { holidays = new Strin ...

  7. 在请求和响应中使用 XML

    偶尔使用 Ajax 的开发人员也会注意到 Ajax 中的 x 并意识到它代表 XML.XML 是编程中最常用的数据格式之一,对于异步应用程序中的服务器响应能够带来切实的好处.在本文中,您将看到服务器如 ...

  8. php 缺少参数,php - 如何验证JSON响应中是否缺少参数-Laravel 6 - 堆栈内存溢出

    我正在为我的应用设置付款网关退款,响应中包含以下字段 message, refundId, status 我从服务器得到的回应, 场景1: {"message":"Tot ...

  9. 掌握 Ajax,第 7 部分: 在请求和响应中使用 XML

    了解什么时候适合什么时候不适合使用 XML 文档选项 打印本页 打印本页 将此页作为电子邮件发送 将此页作为电子邮件发送 级别: 中级 Brett McLaughlin (brett@oreilly. ...

最新文章

  1. OpenBLAS简介及在Windows7 VS2013上源码的编译过程
  2. java中过滤器Filter的使用总结【转载】
  3. Tips6:用[HideInInspector]在Inspector中隐藏变量
  4. vld检测不输出_专业分享丨高频电刀的质量控制检测
  5. php sdk 调用示例,开放服务-SDK调用示例
  6. [bzoj] 2049 洞穴勘探 || LCT
  7. java dispose方法_java-dispose方法
  8. Leetcode每日一题:44.wildcard-matching(通配符匹配)
  9. python画条形图-用Matplotlib如何绘制条形图、直方图和散点图
  10. flex实现水平垂直居中
  11. netty之管道处理流程
  12. 央行DECP开测,拉开全球货币霸权之战大幕 | 凌云时刻
  13. 《机器视觉算法与应用》学习笔记(一)图像采集——照明
  14. Cellular Automaton UVA - 1386
  15. StringWriter介绍
  16. 1. NETSDK1141    无法解析位于  global.json 中指定的 .NET SDK 版本
  17. Shor’s algorithm
  18. 南京Uber优步司机奖励政策(1月18日~1月24日)
  19. 【论文笔记之 CLMS】The Complex LMS Algorithm
  20. Python字符串格式化的3种方法

热门文章

  1. django ajax 简书,Django_ajax
  2. 【3】flink sink
  3. java客户端作为kafka消费者测试
  4. GET与POST传递数据的最大长度能够达到多少
  5. jQuery中的几个案例:隔行变色、复选框全选和全不选
  6. stripe pay_J2Pay –完整示例
  7. arrays.sort(._Arrays.hashCode(Object [])与Objects.hash(Object…)
  8. hazelcast入门教程_Hazelcast入门指南第6部分
  9. java8 streams_当Java 8 Streams API不够用时
  10. λ演算的语法和语义_λ和副作用