采用LDAP提供CARSI身份认证功能,CARSI IdP通过LDAP接口与学校身份认证系统对接。IdP自动安装脚本已经完成基本配置,与学校部署情况相关、需要修改的部分如下。
1. 修改LDAP对接参数
[carsi@www ~]$ sudo vi /opt/shibboleth-idp/conf/ldap.properties ## Connection properties ## # 使用学校的ldap服务器IP地址及端口代替下面的“localhost:10389” idp.authn.LDAP.ldapURL = ldap://localhost:10389 # Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator # for AD: CN=Users,DC=example,DC=org #本地ldap配置中人员所在分支,请根据学校ldap服务器配置进行修改: idp.authn.LDAP.baseDN = ou=people,dc=example,dc=org # bind search configuration # for AD: idp.authn.LDAP.bindDN=adminuser@domain.com #本地ldap配置中查询人员所在分支,请根据学校ldap服务器配置进行修改: idp.authn.LDAP.bindDN = uid=myservice,ou=system #idp.authn.LDAP.subtreeSearch = false #登录本地ldap服务器的用户名,下面配置中user表示IdP密码验证对话框中输入的用户名对应的IdP字段名称,uid指对应的ldap服务器对应的字段名称: idp.authn.LDAP.userFilter = (uid={user}) #检查确认useStartTLS、sslConfig、authenticator三项配置与下面配置一致: idp.authn.LDAP.useStartTLS = false ## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust idp.authn.LDAP.sslConfig = jvmTrust ## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator idp.authn.LDAP.authenticator = bindSearchAuthenticator [carsi@www ~]$ sudo vi /opt/shibboleth-idp/credentials/secrets.properties 设置LDAP服务器查询密码: idp.authn.LDAP.bindDNCredential = "密码"
因LDAP服务器配置差异,请与本校LDAP管理员确认以上配置,需要了解本校LDAP的目录结构以及字段定义后再做修改。以上属性在ldap.properties文件中已经定义好,请勿直接拷贝添加到ldap.properties,会造成属性重复定义,其他未提到的属性按照ldap.properties默认配置即可。
如果LDAP中不是用“uid”来唯一区别用户,请修改成本地LDAP中采用的用户标识名。比如在使用 AD 的情况下,通常使用 sAMAccountName 作为唯一标识,则该部分的配置应该如下所示
idp.authn.LDAP.userFilter = (sAMAccountName={user}) idp.attribute.resolver.LDAP.searchFilter = (sAMAccountName=$resolutionContext.principal)
注:强烈建议先在IdP所在的服务器上测试一下对本校LDAP的连接性,以及查看一下LDAP管理员提供的属性及其取值是否正确。华东师范大学冯骐老师分享了一个轻量级的 LDAP测试工具 https://github.com/shanghai-edu/ldap-test-tool , 可以用来进行测试。或使用类似LDAP Browser或LDAP Admin这样的工具,在IdP所在服务器进行验证,以排除环境问题的影响。
2.配置属性定义
eduPersonScopedAffiliation属性,取值为用户在学校的身份,其中的“employeeType”为本地LDAP中确定用户身份的属性名称,请替换成实际使用的属性名。关于身份属性取值,需要将本地用户身份的取值,对应到CARSI联盟标准取值,包括:faculty(教师),student(学生),staff(教工),employee(雇员),member(各类人员,包括faculty、student、staff、employee),alum(校友),affiliate(附属人员或临聘,常用),other(CARSI补充,不建议优先使用)。下文样例,将所有的本地用户区分为“staff”、“student”、“member”三种身份。学校可根据本地LDAP实际部署情况选取其中的一部分值。不同SP对用户身份的要求不同,建议配置时尽可能细化用户身份分类,避免后期修改配置。
如果学校ldap服务器用目录来区分用户身份的情况,建议在ldap中添加描述用户身份的字段。
注:
1. 请使用学校Ldap服务器用于标识用户身份的字段,替换下面配置文件中所有的”employeeType“,如不知道字段名称,请咨询贵校Ldap管理员。
2. localPart赋值需为CARSI标准取值,区分大小写。
3. 除了身份属性定义外,其他部分不需要修改。
[carsi@www ~]$ sudo vi /opt/shibboleth-idp/conf/attribute-resolver.xml <AttributeDefinition xsi:type="ScriptedAttribute" id="eduPersonScopedAffiliation"> <InputDataConnector ref="myLDAP" attributeNames="employeeType"/> <Script><![CDATA[ scopedValueType = Java.type("net.shibboleth.idp.attribute.ScopedStringAttributeValue"); var localPart = ""; if(typeof(employeeType)=="undefined"){ localPart = "other"; }else{ if(employeeType.getValues().get(0)=="staff") localPart = "staff"; # if条件中“staff”为本地用户管理系统中属性取值,可能是“staf”或其他 else if(employeeType.getValues().get(0)=="student") localPart = "student"; # if条件中“std”为本地用户管理系统中属性取值,可能是“stud”“student”等 else localPart = "member"; } eduPersonScopedAffiliation.addValue(new scopedValueType(localPart, "%{idp.scope}")); ]]></Script> </AttributeDefinition> [carsi@www ~]$ sudo systemctl restart jetty
3. 某学校IdP属性配置文件样本:
注:下面配置文件中 ”employeeType“ 属性字段是由LDAP服务器传送到IdP的,用于标识用户身份的字段,其取值依赖于LDAP服务器的配置,请咨询LDAP管理员。
[carsi@www ~]$ sudo cat attribute-resolver.xml <?xml version="1.0" encoding="UTF-8"?> <AttributeResolver xmlns="urn:mace:shibboleth:2.0:resolver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"> <!-- ========================================== --> <!-- Attribute Definitions --> <!-- ========================================== --> <AttributeDefinition xsi:type="ScriptedAttribute" id="eduPersonScopedAffiliation"> <InputDataConnector ref="myLDAP" attributeNames="employeeType"/> <Script><![CDATA[ scopedValueType = Java.type("net.shibboleth.idp.attribute.ScopedStringAttributeValue"); var localPart = ""; if(employeeType.getValues().get(0)=="faculty") localPart = "faculty"; else if(employeeType.getValues().get(0)=="std") localPart = "student"; else localPart = "member"; eduPersonScopedAffiliation.addValue(new scopedValueType(localPart, "%{idp.scope}")); ]]></Script> </AttributeDefinition> <AttributeDefinition xsi:type="Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}"> <InputAttributeDefinition ref="uid"/> </AttributeDefinition> <AttributeDefinition id="uid" xsi:type="PrincipalName" /> <AttributeDefinition id="eduPersonTargetedID" xsi:type="SAML2NameID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"> <InputDataConnector ref="myStoredID" attributeNames="persistentID"/> <AttributeEncoder xsi:type="SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" encodeType="false"/> <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" encodeType="false"/> </AttributeDefinition> <AttributeDefinition id="samlPairwiseID" xsi:type="Scoped" scope="%{idp.scope}"> <InputDataConnector ref="myStoredID" attributeNames="persistentID"/> </AttributeDefinition> <AttributeDefinition id="eduPersonEntitlement" xsi:type="Simple"> <InputDataConnector ref="staticAttributes" attributeNames="eduPersonEntitlement" /> </AttributeDefinition> <DataConnector id="staticAttributes" xsi:type="Static"> <Attribute id="eduPersonEntitlement"> <Value>urn:mace:dir:entitlement:common-lib-terms</Value> </Attribute> </DataConnector> <DataConnector id="myStoredID" xsi:type="StoredId" generatedAttributeID="persistentID" salt="%{idp.persistentId.salt}" queryTimeout="0"> <InputAttributeDefinition ref="eduPersonPrincipalName"/> <BeanManagedConnection>MyDataSource</BeanManagedConnection> </DataConnector> <DataConnector id="myLDAP" xsi:type="LDAPDirectory" ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}" baseDN="%{idp.attribute.resolver.LDAP.baseDN}" principal="%{idp.attribute.resolver.LDAP.bindDN}" principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}" connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}" responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}"> <FilterTemplate> <![CDATA[ %{idp.attribute.resolver.LDAP.searchFilter} ]]> </FilterTemplate> <ConnectionPool minPoolSize="%{idp.pool.LDAP.minSize:3}" maxPoolSize="%{idp.pool.LDAP.maxSize:10}" blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}" validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}" validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}" expirationTime="%{idp.pool.LDAP.idleTime:PT10M}" failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}" /> </DataConnector> </AttributeResolver>
4. 配置属性释放
IdP安装脚本已经完成属性释放配置,可不修改。