saml2_向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...
saml2
总览
最新版本的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,这些属性已从其他方法中检索出在我们的扩展名中定义。
怎么样?
- 实施定制逻辑以获取外部声明。 我们仅需注意两个事实。
- 定制实现应实现接口“ 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;} }
- 将已编译的OSGI捆绑软件放在IS_HOME / repository / components / dropins中。 (我们将其开发为OSGI捆绑软件,因为我们还需要使用RealmService获得本地声明。 您可以在此处找到完整的捆绑软件和源代码 )
- 使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
saml2
saml2_向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...相关推荐
- 向SAML响应中添加自定义声明–(如何为WSO2 Identity Server编写自定义声明处理程序)...
总览 最新版本的WSO2 Identity Server(版本5.0.0)配备了"应用程序身份验证框架",该框架提供了很大的灵活性,可以对来自使用异构协议的各种服务提供商的用户进行 ...
- 如何编写 TypeScript 声明文件
1. 什么是 TS 声明文件 在 TypeScript 中以 .d.ts 为后缀的文件,称为 TypeScript 声明文件.它的作用是描述 JavaScript 模块内所有导出接口的类型信息. 2. ...
- 蓝牙芯片----BK3431开发笔记------RW stack中添加自定义服务教程(4)
一.实现自定义服务 在 RW 协议栈协议栈中添加一个自定义服务需要实现 6 个文件,分别为: custom.c custom.h custom_task.c custom_task.h app_cus ...
- java saml_java – 验证SAML响应的签名
这是我的工作流程:我收到了SAML响应.我摆脱了签名信封,我将其标准化,检查摘要然后检查签名.我能够成功计算转换后的SAML响应的SHA1摘要并验证它.但是,RSA-SHA1签名检查仍然无法解决. 我 ...
- 向DataTable中添加自定义的行
[标题]向DataTable中添加自定义行 [内容] 向DataTable中添加自定义行,然后绑定到DropDownList控件中,并且默认行为控件的第一行 如果表结构如下: ...
- html怎样添加日历控件,向日历控件中添加自定义内容
向日历控件中添加自定义内容 String[][] holidays; void Page_Load(Object Sender, EventArgs e) { holidays = new Strin ...
- 在请求和响应中使用 XML
偶尔使用 Ajax 的开发人员也会注意到 Ajax 中的 x 并意识到它代表 XML.XML 是编程中最常用的数据格式之一,对于异步应用程序中的服务器响应能够带来切实的好处.在本文中,您将看到服务器如 ...
- php 缺少参数,php - 如何验证JSON响应中是否缺少参数-Laravel 6 - 堆栈内存溢出
我正在为我的应用设置付款网关退款,响应中包含以下字段 message, refundId, status 我从服务器得到的回应, 场景1: {"message":"Tot ...
- 掌握 Ajax,第 7 部分: 在请求和响应中使用 XML
了解什么时候适合什么时候不适合使用 XML 文档选项 打印本页 打印本页 将此页作为电子邮件发送 将此页作为电子邮件发送 级别: 中级 Brett McLaughlin (brett@oreilly. ...
最新文章
- PowerPC VxWorks BSP分析7——image压缩
- 这篇长达165页的论文,用一个里程碑式的证明同时解决了量子物理学和理论数学的难题...
- spring配置JDBC事务
- 用Python和Pygame写游戏-从入门到精通(1)
- 求1到n ,这n个整数的二进制表示比特1的个数(时间复杂度:O(n))
- system流怎么判断为空_并行流ParallelStream中隐藏的陷阱
- BGP——BGP优化技术(总结+配置)
- C/C++排序算法(3)冒泡排序
- wangEditor 全屏 预览 查看源码
- 用Python webdriver图书馆抢座自动预约的正确姿势
- 苹果怎么用微信链接服务器,苹果手机如何设置微信登陆锁
- 前5名:Raspberry Pi龙卷风警告系统,用于物联网开发的4个开放式开发板等
- X86与ARM平台下的参数传递机制
- 亚麻种子的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- C语言入门——C语言概述
- 计算关联系数matlab,matlab相关系数计算公式
- 女生应该找一个会打DOTA的男生做老公
- 【Vulkan学习记录-基础篇-1】用Vulkan画一个三角形
- 宁波银行金融科技面试
- ping命令的几个简单使用