IdP认证对接及属性定义(OAuth2)(ova第3/6步,手动第3/9步)
本文档介绍了采用CARSI IdP标准安装包对接OAuth2认证和属性定义的配置步骤,适用于本地采用oauth2认证的情况。下一步:配置eduPersonTargetedID属性定义。
关于详细的OAuth2对接细节,可同时参考:Shibboleth-IdP 的 OAuth2 对接方案详解(感谢华东师范大学冯骐老师提供)
OAuth2认证需要采用标准的授权码(Authorization Code)方式,简单过程如下:
(1)IdP跳转到OAuth2认证页面,用GET方式传递response_type、client_id、state、redirect_uri四个参数;
(2)认证通过后,OAuth2回调到redirect_uri上并带上code参数;
(3)IdP获取code,向OAuth2获取token,用POST方式传递,grant_type=authorization_code、code、client_id、client_secret、redirect_uri;
(4)OAuth2验证后,返回token;
(5)IdP获取token后,向OAuth2请求资源,用POST方式传递token;
(6)OAuth2返回IdP相应的资源。
需要OAuth2管理员提供:
OAuth2认证页面URL、OAuth2用code获取token的URL、OAuth2用token获取资源的URL、IdP认证在OAuth2上的client_id、client_secret
向OAuth2管理员提供:
redirect_uri=https://xxx.xxx.edu.cn/idp/Authn/ExtOauth2?conversation=e1s1
具体配置:
(1)新建文件夹并拷贝相关文件:
[root@www ~]# mkdir /opt/shibboleth-idp/flows/authn/Shiboauth2
把 3.2.4-oauth-bundle.zip 中shibcas-authn-beans.xml、shibcas-authn-flow.xml放入文件夹中。
把附件中的no-conversation-state.jsp放入/opt/shibboleth-idp/edit-webapp中。
把附件中的shib-cas-authenticator-3.2.4-oauth.jar 、cas-client-core-3.4.1.jar放入/opt/shibboleth-idp/edit-webapp/WEB-INF/lib中。
(2)配置web.xml:
[root@www ~]# cp /opt/shibboleth-idp/dist/webapp/WEB-INF/web.xml /opt/shibboleth-idp/edit-webapp/WEB-INF/web.xml [root@www ~]# vi /opt/shibboleth-idp/edit-webapp/WEB-INF/web.xml #在<!-- Servlets and servlet mappings -->后加上 <!-- Servlet for receiving a callback from an external CAS Server and continues the IdP login flow --> <servlet> <servlet-name> ShibOauth2 Auth Servlet</servlet-name> <servlet-class>net.unicon.idp.externalauth.ShibcasAuthServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name> ShibOauth2 Auth Servlet</servlet-name> <url-pattern>/Authn/ExtOauth2/*</url-pattern> </servlet-mapping>
(3)配置idp.properties:
注意 shibcas.oauth2principalname 必须配置为 oauth 释放的属性中,表示为用户名的那个字段(即用于映射 princleName 的那个)
[root@www ~]# vi /opt/shibboleth-idp/conf/idp.properties #修改 idp.authn.flows = Shiboauth2 #新增 shibcas.oauth2UrlPrefix = http://xxx.xxx.xxx.xxx #OAuth2服务器域名 shibcas.oauth2LoginUrl = ${shibcas.oauth2UrlPrefix}/xxx?response_type=code&client_id=xxx&state=xyz #OAuth2认证页面以及需要传递的参数,state可以配置成任意字符串 shibcas.serverName = https://xxx.xxx.xxx.xxx #IdP的域名 shibcas.oauth2TokenUrl = http://xxx.xxx.xxx.xxx/xxx # OAuth2用code获取token的URL shibcas.oauth2ResourceUrl = http://xxx.xxx.xxx.xxx/xxx # OAuth2用token获取资源的URL shibcas.oauth2clientid = testclient shibcas.oauth2clientsecret = testpass shibcas.oauth2redirecturi = https://xxx.xxx.xxx/idp/Authn/ExtOauth2?conversation=e1s1 # 新增 shibcas.oauth2redirecturiBase = https://xxx.xxx.xxx.xxx/idp/Authn/ExtOauth2 shibcas.oauth2principalname = uid # oauth 释放属性中,作为用户名输入的那个字段。这个字段必须存在,不然会报错
(4)配置general-authn.xml:
[root@www ~]# vi /opt/shibboleth-idp/conf/authn/general-authn.xml #在<util:list id="shibboleth.AvailableAuthenticationFlows">后新增 <bean id="authn/Shiboauth2" parent="shibboleth.AuthenticationFlow" p:passiveAuthenticationSupported="true" p:forcedAuthenticationSupported="true" p:nonBrowserSupported="false" />
(5)配置属性释放,用以下内容替换/opt/shibboleth-idp/conf/attribute-resolver.xml文件:
xsi:type="SubjectDerivedAttribute"
的 AttributeDefinition 标识从插件中获取属性的配置
例如下面的示例表示,从 OAuth 中获取的 role 属性,映射为 shibboleth 中的 eduPersonScopedAffiliation,从 OAuth 中获取的 uid 属性,映射为 shibboleth 中的 eduPersonPrincipalName
<?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"> <AttributeDefinition xsi:type="ScriptedAttribute" id="eduPersonScopedAffiliation"> <InputAttributeDefinition ref="usertype" /> <Script><![CDATA[ var localpart = ""; if(typeof(usertype)=="undefined"){ localpart = "member"; }else{ if(usertype.getValues().get(0)=="staf") localpart = "staff"; else if(usertype.getValues().get(0)=="std") localpart = "student"; else localpart = "member"; } if(usertype.getValues().get(0)=="staf") localpart = "staff"; else if(usertype.getValues().get(0)=="std") localpart = "student"; else localpart = "member"; eduPersonScopedAffiliation.addValue(localpart + "@%{idp.scope}"); ]]></Script> <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" encodeType="false" /> <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" encodeType="false" /> </AttributeDefinition> <AttributeDefinition xsi:type="SubjectDerivedAttribute" id="usertype" principalAttributeName="role"></AttributeDefinition> <AttributeDefinition id="eduPersonPrincipalName" xsi:type="Scoped" scope="%{idp.scope}"> <InputAttributeDefinition ref="PrincipalName" /> <AttributeEncoder xsi:type="SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" /> <AttributeEncoder xsi:type="SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" /> </AttributeDefinition> <AttributeDefinition xsi:type="SubjectDerivedAttribute" id="PrincipalName" principalAttributeName="uid"></AttributeDefinition> <AttributeDefinition id="eduPersonEntitlement" xsi:type="Simple"> <InputDataConnector ref="staticAttributes" attributeNames="eduPersonEntitlement" /> <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:eduPersonEntitlement" encodeType="false"/> <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" friendlyName="eduPersonEntitlement" encodeType="false"/> </AttributeDefinition> <DataConnector id="staticAttributes" xsi:type="Static"> <Attribute id="eduPersonEntitlement"> <Value>urn:mace:dir:entitlement:common-lib-terms</Value> </Attribute> </DataConnector> </AttributeResolver>
(6)重新编译war文件,并且重启tomcat:
[root@www ~]# cd /opt/shibboleth-idp/bin [root@www ~]# ./build.sh Installation Directory: [/opt/shibboleth-idp] #enter Rebuilding /opt/shibboleth-idp/war/idp.war ... ...done BUILD SUCCESSFUL Total time: 3 seconds [root@www ~]# systemctl restart tomcat
OAuth 服务端备注:
OAuth 服务端需要提供一个资源属性接口,支持 POST 方式请求。为了便于标准化属性的获取,接口应该避免层级嵌套。(参考 https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)。并讲表示用户名的字段,填入配置文件的 shibcas.oauth2principalname 中
例如如下的返回中,如果用户名是 666666,那么 shibcas.oauth2principalname = uid
# curl -X POST -d "access_token=e4d051380887c2ead8a5faa4fc2cee75" https://oauth.xxx.edu.cn/userinfo { "cn": "我是名字", "eduPersonAffiliation": "student", "uid": "666666" }
下一步:配置eduPersonTargetedID属性定义。
版权所有©北京大学计算中心