This page describes how to integrate Seam's Identity component (a.k.a - Seam Security) with a CAS Server. My approach is based on the Yale CAS Client distribution. See also here and here
1. web.xml
Configure your web.xml as directed in the Yale CAS Client distribution docs to use CAS for login and logout.
...
Code Block | ||
---|---|---|
| ||
<!-- CAS Logout Filter and Logout Mapping-->
<filter>
<filter-name>LogoutFilter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.LogoutFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.logoutUrl</param-name>
<param-value>https://YOUR_CAS_SERVER_HOST_ADDRESS_HERE/cas/logout</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogoutFilter</filter-name>
<url-pattern>/logout/*</url-pattern>
</filter-mapping>
|
2. Write a Seam-Identity authenticator class / component:
Code Block | ||
---|---|---|
| ||
@Name("ssoAuthenticator")
@Scope(ScopeType.SESSION)
public class SSOAuthenticator {
@Logger
private Log log;
private UserPrincipal userPrincipal;
// see http://www.jboss.com/index.html?module=bb&op=viewtopic&t=119167
// This method is configured in pages.xml as an action called for all pages:
// <page view-id="/*" login-required="true" action="#{authenticator.checkLogin}"/>
public void checkLogin() {
final boolean isLoggedIn = Identity.instance().isLoggedIn();
// user may already be logged in - check
if (isLoggedIn) {
return;
}
authenticate();
}
public boolean authenticate() {
Identity identity = Identity.instance();
boolean authenticated = !(userPrincipal == null);
if (!authenticated) {
try {
// Obtain authenticated UserPrincipal from Servlet container
FacesContext facesContext = FacesContext.getCurrentInstance();
Principal rawPrincipal = facesContext.getExternalContext().getUserPrincipal();
userPrincipal = (UserPrincipal) rawPrincipal;
// trigger the identity login sequence and add roles
if (userPrincipal != null) {
// Identity must have 'fresh' credentials for authenticat() call to proceed
identity.setUsername(userPrincipal.getUserid());
identity.setPassword(userPrincipal.getUserid());
identity.authenticate();
// in my case, our system makes roles available in the UserPrincipal,
// do what is right for your system
Group[] roleGroups = userPrincipal.getUserRoles();
if (roleGroups != null) {
for (Group group : userPrincipal.getUserRoles()) {
Enumeration<? extends Principal> roles = group.members();
while (roles.hasMoreElements()) {
identity.addRole(roles.nextElement().getName());
}
}
}
authenticated = true;
}
} catch (Exception e) {
log.error(e, e);
}
}
return authenticated;
}
}
|
2. pages.xml
Configure Seam's pages.xml file in your web app to use your authenticator.
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd"
no-conversation-view-id="/index.xhtml">
<page view-id="/index.xhtml" action="#{ssoAuthenticator.checkLogin}" login-required="false"/>
<page view-id="/*" login-required="true"/>
<exception class="org.jboss.seam.security.NotLoggedInException">
<redirect view-id="/index.xhtml">
<message>Please log in first</message>
</redirect>
</exception>
...
</pages>
|