PicketLink是一个开源的安全框架(不便于集成,需要二次开发),为Java EE应用提供安全(认证、授权、权限访问API)和IDM方案。在WildFly AS 10中,默认已经提供了对PicketLink 2.5.5.SP1的集成。
基于PicketLink,可以在WildFly AS 10中实现兼容SAML标准的SSO。
1.基于SAML的SSO概述
1)SSO中的几个概念
Service Provider (SP)就是部署在应用服务器上的各个应用。
IdentityProvider (IdP),负责对SP的访问请求进行身份验证。2)SP发起的SSO处理过程
a.用户请求访问SP(就是一个普通的Web应用)
b.SP代理检查用户请求的授权,如果用户还没有被认证则将请求重定向到IdP
c.IdP给出登录页面,用户输入认证信息
d.IdP查询数据库,检查用户输入的有效性
e.如果用户有效,IdP为该用户创建一个会话,并签发一个SAML Assertion
f.IdP将带有SAML Assertion 和用户信息的用户请求返回给SP
g.SP检查SAML Assertion 确认用户有效
h.SP检查用户的权限,授权用户访问应用
2.基于PicketLink的IdP(Identity Provider)应用的配置
IdP也是一个Web应用,集中负责对用户信息的认证并签发SAMLAssertion 。
SAML Assertion 就是IdP认证后为用户签发的一个信息集合,这些信息是从用户识别数据库(如LDAP或数据库等)中获取的。SAMLAssertion 用于SP对用户的鉴权。
IdP的配置如下:
1) 在WEB-INF/web.xml中,设置安全约束和登录配置
<security-constraint>
<web-resource-collection>
<web-resource-name>Manager command</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
<role-name>Sales</role-name>
<role-name>Employee</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>PicketLink IDP Application</realm-name>
<form-login-config>
<form-login-page>/jsp/login.jsp</form-login-page>
<form-error-page>/jsp/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
注意,安全约束中,采用了基于角色的访问限制;用户的认证,采用了基于FORM的认证。
这样,未经认证的用户,其请求将总是被传递信息到登录配置的页面。
2) 在WildFly AS 10的启动配置文件${JBOSS_HOME}/standalone/configuration/standalone-full.xml中,设置安全域
<security-domain name="idp" cache-type="default">
<authentication>
<login-module code="UsersRoles" flag="required">
<module-option name="usersProperties" value="users.properties"/>
<module-option name="rolesProperties" value="roles.properties"/>
</login-module>
</authentication>
</security-domain>
注意,这里设置的安全域采用了两个属性文件,它们位于WEB-INF/classes/。事实上,应该使用LDAP或数据库保存用户和角色信息。
3) IdP为了引用服务器提供的安全域,在WEB-INF/jboss-web.xml中引用安全域
<jboss-web>
<security-domain>idp</security-domain>
</jboss-web>
至此,IdP能够对用户进行认证。
但是具体的认证过程,是由PicketLinkAuthenticator完成的。PicketLinkAuthenticator是PicketLink提供的一个组件,专门用于处理SAML消息。
4) 在WildFly AS 10中,为了启动对应的PicketLinkAuthenticator,需要在WEB-INF/web.xml中配置过滤器
<filter>
<filter-name>IDPFilter</filter-name>
<filter-class>org.picketlink.identity.federation.web.filters.IDPFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>IDPFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5) 在WEB-INF/picketlink.xml中,配置IdP的参数
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
<PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1">
<IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>
<Trust>
<Domains>localhost,jboss.com,jboss.org,viavi.com</Domains>
</Trust>
</PicketLinkIDP>
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureGenerationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler" />
</Handlers>
</PicketLink>
6) 在META-INF/jboss-deployment-structure.xml中,设置IdP部署时对的依赖
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.picketlink"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
3.基于PicketLink的SP(Service Provider)应用的配置
SP也是一个Web应用,提供一定的业务功能。SP依赖于IdP签发的以对用户进行鉴权。
集中负责对用户信息的认证并签发SAMLAssertion 。
SP的配置过程如下:
1) 在WEB-INF/web.xml中,设置安全约束和登录配置
<security-constraint>
<web-resource-collection>
<web-resource-name>Manager command</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
注意,安全约束中,采用了基于角色的访问限制,只有manager角色能够访问该SP。
2) 在WildFly AS 10的启动配置文件${JBOSS_HOME}/standalone/configuration/standalone-full.xml中,设置安全域
<security-domain name="sp" cache-type="default">
<authentication>
<login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule" flag="required"/>
</authentication>
</security-domain>
3) SP为了引用服务器提供的安全域,在WEB-INF/jboss-web.xml中引用安全域
<jboss-web>
<security-domain>sp</security-domain>
</jboss-web>
至此,SP能够对用户进行鉴权。
4) 在WildFly AS 10中,为了启动对应的PicketLinkAuthenticator,需要为SP创建/WEB-INF/classes/META-INF/services/io.undertow.servlet.ServletExtension文件,文件内容如下
org.picketlink.identity.federation.bindings.wildfly.sp.SPServletExtension
5) 在WEB-INF/picketlink.xml中,配置SP的参数
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1" BindingType="POST">
<IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>
<ServiceURL>${sales-post.url::http://localhost:8080/sales-post/}</ServiceURL>
</PicketLinkSP>
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
</Handlers>
</PicketLink>
6) 在META-INF/jboss-deployment-structure.xml中,设置IdP部署时对的依赖
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.picketlink"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
参考文献:
PicketLink Quickstarts源代码 https://github.com/jboss-developer/jboss-picketlink-quickstarts
PicketLink SSO http://picketlink.org/gettingstarted/saml_sso/