« 返回到 Single Sign-on

OpenAM Policy Agent Integration

The purpose of this document is to give a step by step tutorial to authenticate users against OpenAM / OpenSSO with Liferay behind a Policy Agent. We assume that you have OpenAM up and running with Policy Agent available. I won't discuss how to set them up here, I'll just give the Policy Agent configuration necessary to make it all work.

Architecture Overview #

VERY IMPORTANT SECURITY COMMENT

As our system entirely relies on trusting HTTP_HEADERS incoming from the Policy Agent, it is mandatory to protect Liferay and its application server against direct HTTP connection that would bypass the Policy Agent. You can use whatever technique you want to avoid this, including AS Binding or VLANs.

How to ? #

Configuring OpenAM / OpenSSO Policy Agent #

Not enforced URLs #

We will configure the Policy Agent so that it lets public pages available without auth. This implies not ot enforce /web, themes, the company logo, login and logout URLs. The agent configuration shall look as follows :

com.sun.identity.agents.config.notenforced.url[0] = https://liferay.starbuck.localdomain:443/web/*
com.sun.identity.agents.config.notenforced.url[1] = https://liferay.starbuck.localdomain:443/html/*
com.sun.identity.agents.config.notenforced.url[2] = https://liferay.starbuck.localdomain:443
com.sun.identity.agents.config.notenforced.url[3] = https://liferay.starbuck.localdomain:443/combo/*
com.sun.identity.agents.config.notenforced.url[4] = https://liferay.starbuck.localdomain:443/image/company_logo*
com.sun.identity.agents.config.notenforced.url[5] = https://liferay.starbuck.localdomain:443/
com.sun.identity.agents.config.notenforced.url[6] = https://liferay.starbuck.localdomain:443/c/portal/login*
com.sun.identity.agents.config.notenforced.url[7] = https://liferay.starbuck.localdomain:443/c/portal/logout*
com.sun.identity.agents.config.notenforced.url.invert = false
com.sun.identity.agents.config.notenforced.url.attributes.enable = true
com.sun.identity.agents.config.notenforced.ip[0] =

Note that com.sun.identity.agents.config.notenforced.url.attributes.enable has been set to true, so that an already identified user landing on a not enforced URL page could still be authenticated onto Liferay.

Configuring headers #

In this case, we will authenticate the user against Liferay throught its EMail Address. Thus, OpenAM's Policy Agent is configured that way :

com.sun.identity.agents.config.response.attribute.fetch.mode = HTTP_HEADER

com.sun.identity.agents.config.response.attribute.mapping[mail] = HTTP_MAIL

In this case, we've chosen to use Session Attributes to fill up Headers. We also use other headers (cn, sn, givenName), but they're not relevant for Liferay auth.

Configuring Liferay #

Considering Liferay, we will have to go through the following steps :

  • Enable SiteMinder auth
  • Enable OpenSSO auth
  • Enable LDAP sync
  • Tune autologin hooks order

And as promised, everything's happening inside portal-ext.properties !

Enable SiteMinder auth #

siteminder.auth.enabled=true
siteminder.import.from.ldap=true
siteminder.user.header=HTTP_MAIL

As you can see, the value of siteminder.user.header corresponds to the Policy Agent configuration key com.sun.identity.agents.config.response.attribute.mapping[mail]. Don't forget to fill in with what reflects your configuration :)

Enable OpenSSO auth #

open.sso.auth.enabled=true
open.sso.login.url=https://openam.starbuck.localdomain:443/opensso/UI/Login?realm=/starbuck&goto=https://liferay.starbuck.localdomain
open.sso.logout.url=https://openam.starbuck.localdomain:443/opensso/UI/Logout?goto=https://liferay.starbuck.localdomain
open.sso.service.url=https://openam.starbuck.localdomain:443/opensso
open.sso.screen.name.attr=uid
open.sso.email.address.attr=mail
open.sso.first.name.attr=givenname
open.sso.last.name.attr=sn
open.sso.logout.on.session.expiration=false

We activate OpenSSO auth here, but we will not use it at all. We just want to use an out of the box way to tune the actions behind the "Sign In" and "Sign Out" buttons in Liferay.

open.sso.login.url takes two important arguments :

  • realm : the realm you want your users to identify to. If you're using / as realm, you can just get rid of this parameter. Note that specifying realm seems to become optional in the upcoming 10.0 OpenAM release.
  • goto : this is a very important argument as it's the callback URL OpenAM will redirect the user to after successfull login. Please see Liferay's OpenSSO auth documentation for further details.

open.sso.logout.on.session.expiration has been set to false as we want OpenAM to be the reference for the session's duration.

Enable LDAP Sync #

ldap.base.provider.url.0=ldap://openam.starbuck.localdomain:389/
ldap.base.dn.0=dc=starbuck,dc=localdomain
ldap.security.principal.0=cn=Directory Manager
ldap.security.credentials.0=changeit

ldap.auth.enabled=false
ldap.import.enabled=true
ldap.export.enabled=true

ldap.import.method=user

ldap.import.interval=10
ldap.import.on.startup=true

ldap.auth.search.filter.0=(mail=@email_address@)
ldap.users.dn.0=ou=people,dc=starbuck,dc=localdomain
ldap.groups.dn.0=ou=groups,dc=starbuck,dc=localdomain
ldap.user.mappings.0=screenName=uid\npassword=userPassword\nemailAddress=mail\nfirstName=givenName\nlastName=sn\njobTitle=title\ngroup=groupMembership
ldap.user.custom.mappings.0=
ldap.contact.mappings.0=
ldap.contact.custom.mappings.0=
ldap.group.mappings.0=groupName=cn\ndescription=description\nuser=uniqueMember
ldap.import.user.search.filter.0=(objectClass=iplanet-am-auth-configuration-service,sunIdentityServerLibertyPPService,sunAMAuthAccountLockout,sunFederationManagerDataStore,iplanet-am-managed-person,iPlanetPreferences,sunFMSAML2NameIdentifier,person,inetorgperson,organizationalperson,inetuser,iplanet-am-user-service,top)
ldap.import.group.search.filter.0=(objectClass=groupOfUniqueNames)
ldap.import.user.password.enabled=false
ldap.import.user.password.autogenerated=true

users.reminder.queries.enabled=false
users.reminder.queries.custom.question.enabled=false

Nothing very specific here : LDAP auth is disabled, LDAP sync is on and set. In this case, LDAP connection is made without any encryption (and a dummy password :)) since this configuration has been done on a test environment :)

Things to notice :

  • The configuration is pointing at OpenAM's underlying OpenDJ LDAP Server
  • ldap.import.user.search.filter.0 has been set to all the values required by OpenAM
  • No password import since we don't need it
  • A few lines have been added to disable user reminder queries as authentication and account management is the purpose of OpenAM.

Tune autologin hooks order #

auto.login.hooks=com.liferay.portal.security.auth.SiteMinderAutoLogin,com.liferay.portal.security.auth.OpenSSOAutoLogin

In Liferay's default configuration, OpenSSOAutoLogin is fired before SiteMinder's auth. In our case, this would make Liferay always use iPlanetDirectoryPro token to login and never use HTTP_HEADERS, which is not our goal. Thus, we set the order to first use SiteMinderAutoLogin, which will fail in case there is no OpenAM session opened and take precedence over OpenSSOAutoLogin in case OpenAM's session is opened.

Why this page ? #

There are already very good tutorials dealing with Liferay's integration with OpenSSO / OpenAM. Yet, those only cover dealing with the iPlanetDirectoryPro token. The cycle is simple : retrieve the token if it's not available by redirecting to OpenAM's login page. Then back to Liferay, get iPlanetDirectoryPro, send it to OpenAM to retrieve the user's attribute list, then authenticate. This works like a charm but forces Liferay/Apache to send two HTTP requests to OpenAM's server. The aforementioned architecture makes Liferay rely on HTTP Headers, which needs at most one back and forth with OpenAM Server.

SiteMinder already provides Liferay with an authentication scheme that allows authentication through HTTP_HEADERS. With SiteMinder auth, you can set the HTTP header Liferay will rely on (and even import from LDAP). Unfortunately, using the sole SiteMinder authentication makes "Sign Out" unavailable. It fires Liferay's internal session kill then redirects the user onto Liferay with its OpenAM session still active which makes Liferay reauthenticate. Second point is that, if you allow unauthenticated access to Liferay's public pages (/web/guest/home for example), then, the "Sign In" button will not redirect you to OpenAM's login page.

The central position of a portal makes having the "(Single) Sign Out" button on its pages have sense. Moreover, most public portals have pages that shall be rendered without authentication which is only needed to access protected resources or premium services. The method depicted in this page makes the most of both worlds. It enables HTTP_HEADERS based auth and enables "Sign In" and "Sign Out" buttons. This method is a mix of SiteMinder auth and OpenSSO auth that makes everything possible without developing a hook or anything else, just a little configuration.

1 附件
57573 查看
平均 (1 投票)
满分为 5,平均得分为 5.0。
评论
讨论主题回复 作者 日期
Moreover, it should support CDSSO (Cross Domain... Denis Signoretto 2014年3月21日 上午3:40
I'm testing (implementing) this approach by... Michel Wicky 2014年11月20日 上午8:08
Noted the property exists for web policy agent... Michel Wicky 2014年11月20日 下午11:12

Moreover, it should support CDSSO (Cross Domain Single Sign On), isn't it ?
在 14-3-21 上午3:40 发帖。
I'm testing (implementing) this approach by using openAM 12.0.0 (nightly build 20141101) and don't find com.sun.identity.agents.config.notenforced.url.attributes.enable anymore as Not Enforced URL Processing properties. Any idea ?
在 14-11-20 上午8:08 发帖。
Noted the property exists for web policy agent but not for jee policy agent in openAM console. I'm installing this concept by using a Tomcat7 (for each of liferay and openAM servers) implementation with jee policy agent.
在 14-11-20 下午11:12 发帖以回复 Michel Wicky