Tag Archives: single sign on authentication

SAML SSO with Shibboleth

Original Source – SAML SSO with Shibboleth

How to benchmark OX for a large scale deployment

OX was designed from the ground up to support clustered deployments. The application is stateless: no HTTP sessions are ever used. Even in a two-step authentication, it is not assumed that step one and step two will be handled by the same server. For this reason, OX can be clustered with any load balancer algorithm, for example, round-robin or failover.

Authentication services are only as robust and performant as their underlying persistence mechanisms.

OX uses the LDAPv3 interface for persistence of configuration, user data, and session information. The best two open source LDAP servers are OpenDJ and OpenLDAP. The best non-open source LDAP server is UnboundID. UnboundID also offers an LDAP proxy. To maximize the performance of an LDAP server, the entire dataset must be stored in memory–including the data and the indexes. Even for write performance, keeping the dataset in memory (and proper indexing of course), is necessary.

For a large scale deployment, where the entire data set cannot be stored in one LDAP server’s memory, the best strategy is to split the data up in two servers. For example, store users with last name A-M in one set of servers, and last name N-Z in another set of servers. In this case, the UnboundID proxy can use a cross-sever “global” index to route requests to the respective server that holds the entry.

OpenID Connect and UMA offer many endpoints to benchmark.

The OpenID Connect endpoints are :


The UMA endpoints are :


Furthermore, oxTrust provides SCIM endpoints, which can be used for identity and credential management, and provides additional interactive business logic.

One important consideration for scalability is logout. For example, millions of clients polling repeatedly to make sure their session is still valid is a waste of valuable server resources. OpenID Connect defines a javascript session management mechanism. In this schema, javascript is inserted into each web page, and this polls a local browser flag to find out if another tab has logged out.

The approach can be problematic if the tab is not present when the logout occurs (i.e. the application may not be notified of the logout). If this mechanism is deemed insufficient for the requirements, an alternate logout strategy will need to be devised. Normally this may include using a callback to the registered back-end applications either in serial or parallel.

Benchmarking is an interactive process where the results of one iteration are used to optimize the starting configuration of the next iteration. The components of the infrastructure need to be tested individually. It is then important that the tests try to replicate the expected usage patterns.

For the OX APIs, Gluu can assist in the creation of test data, generation of the load, monitoring of the JVM for memory and connection leaks, and reporting on the resulting throughput.

For LDAP, the SLAMD tool is available. This tool provides load generation, measurement, system performance, and throughput reporting. The tool can be customized to include the collection of custom metrics to enable correlation of performance to OX API usage. Another consideration is to run long lived tests to make sure that replication data does not bloat entry size and negatively effect performance.

To CAS or not to CAS


Is CAS the hidden gem of authentication API’s or should it be end-of-life? Unequivocally, Gluu’s position is the latter–CAS filled a needed gap at the time, but now application developers should be discouraged from expanding the use of CAS. Here is why…


Developed at Yale in the early 2000’s, CAS is now hosted by Jasig, a consortium that fosters open source software projects for higher education. CAS version 2.0 was finalized in 2005 about two years before the iPhone was introduced. CAS is known for its developer friendly (easy) client API. There are lots of CAS libraries for different programming languages, and many plugins are available for other open source projects. Its also supported by some vendors. For even more background, Wikipedia gives an informative overview of CAS.

Why not use CAS?

There are a few reasons you should steer clear.

CAS does not support OAuth2, and it probably never will. Faceook, Google, and Yahoo use OAuth2 for authentication, which represents about 85% of consumer authentications according to Janrain (provider of a widely used uber-authentication-api). Large consumer IDPs that are using OAuth2 are likely to quickly adopt the “OpenID Connect” profile of OAuth2, which will incentivize a staggering number of websites to follow. This will overshadow all previous web SSO/federation standards like CAS, old versions of OpenID, old versions of OAuth, and even SAML.

If you compare CAS and OpenID Connect, you’ll see not only does CAS have less features for authentication, but it does not support many of the endpoints defined by Connect: dynamic client registration, discovery, user claims, client claims. So its not just a matter of a different protocol for authentication, but a lot of missing functionality.

Even SAML support is weak. Many institutions that want both CAS and idp SAML use a “Login Handler” in the Shibboleth SAML IDP software to validate the username/password creds against the CAS server. In this way, the person gets both a CAS token and a SAML token, and has SSO with both kinds of apps.

In CAS, its not that easy to implement new types of multi-step authentication. Most deployments of CAS are for username/password authentication.

While its easy for mobile applications to use the CAS API to validate credentials, the protocol does not lend itself to more complex authorization scenarios where the backend services have different levels of permissions.


Like the little ant, OpenID Connect has high hopes. Where possible, use it. Make sure developers understand the roadmap for your organization: your domain, like all the other domains on the Internet, will adopt OpenID Connect. Use SAML to fill in the gaps until all the OpenID Connect libraries and web server plugins are available. SAML is going to be around much longer than CAS, so its a better bridge solution. Use CAS only as a last resort. You should require products and software that supports the identity integration method that align with your roadmap. Be flexible…using CAS is better than the app storing its own passwords. However, realize that this application will probably never support the two factor authentication services available in OAuth2 and SAML. There are many “good” legacy SSO protocols, don’t forget Siteminder in the Enterprise world… however, if you’re faced with the situation… try NOT TO CAS.

Using OX for Social Login

So you have a website or mobile application, and you want to support social login? Consider using the following imaginary website for Acme Incorporated. Instead of your local username and password, you decide to use the “Login with Yahoo” button.

OX enables a domain to define custom authentication scripts. When you click the “Login with Yahoo” button, the login page uses Acme’s OpenID Connect API (served by OX), and includes the GET parameters “auth_mode=yahoo”. This enable OX to select the correct authentication script for Yahoo. This script could use the Yahoo API to validate your current session or to re-direct you for authentication.

Once you are authenticated, you can see a portal with several panels. Each panel is served by a different back-end web server which needs to know your identity in order to display the right content.

Its a bad idea to instruct each backend web application to use the social API directly. If you did that, each application would have to implement business logic for every social login API. If Yahoo or Google updates their API, every application would have to update their code. Plus, introducing new authentication mechanisms would be difficult: you’d have to get every app to do so.

Using the social login API directly could make it hard for the backend web applications to get all the needed information about you. For example, the billing application might need your Acme account number, which Yahoo does not know.

But how does Acme know which person corresponds to which social account? This is where you need to consider enrollment. Frequently, a person with a local account specifies that they want to associate a social account. Or if you first authenticate with a social login, you may need to provide additional information–for example address, phone number, account number–to enable the organization to setup a local account.

In many ways using a social login API is no different from the considerations of using any external authentication provider, for example Duo or OneID. A custom authentication script could even support uber-authentication API’s, like Janrain or Gigya. These services would enable you to create one custom authentication script to support multiple consumer IDP’s.

The key takeaway from this should be the following: within your domain, stick to open standards like OpenID Connect and SAML. This gives you the most flexibility to change your business logic for authentication, without having to update your applications.

Gluu vs. Ping Identity – a (mostly) unbiased comparison

We know that the strength of open standards is that customers will be able to choose from many commercial and open source solutions. We believe more gas stations on the corner means more business for everyone.

We “enjoy” competing with Ping, if that’s possible. Ping provides greatly needed support for open standards, and has literally hosted the ecosystem of companies in their hometown and abroad at many great events. Not surprisingly, we frequently get asked the question: How does Gluu compare to Ping? In the interest of efficiency, we decided to write this blog to help explain what are some of the reasons why some customers might prefer Gluu… or Ping.

If you fit into one of these categories, you may prefer to go with Gluu Green:

You want Open Source. Either you are paranoid, and you actually want to read all the code. Or you have realized that open source is simply the best development model for writing servers based on open Internet standards.

You want OpenID Connect or UMA today. Compare the current results of Ping and Gluu from the latest OpenID Connect Interop (#5). Its going to take Ping a long time to write all that code. And there are even more endpoints and tokens for UMA.

Gluu offers tools for Multi-Party federations. This type of federation is used extensively in higher education and government. It provides both the tools and rules to enable networks of autonomous IDPs and RPs to drive down the cost of SSO, improve security and protect privacy.

You want a managed service. Gluu’s use of Puppet to standardize delivery of the OX stack offers a compromise between a multi-tenant SaaS identity offering (PingOne), and an enterprise software deployment (PingFederate). It offers the operational advantage of a SaaS service, without the security and privacy dis-advantage of storing PII on shared servers.

You don’t want to pay per user or per application. The Gluu Server subscription offers a predictable annual operational cost. There are no per-user or per connection fees even for strong multi-factor

Five Interceptions of the OX OP

Gluu has designed OX to be very flexible. OX admins can use Jython scripts to customize behavior.

Jython was chosen because an interpreted language facilitates dynamic creation of business logic, and makes it easier to distribute this logic to a cluster of OX servers. Another advantage of Jython was that developers can use either Java or Python classes. Combined with the option of calling web services from Python or Java, this enables OX to support any crazy requirement. Domains can use OX “interception” scripts to code their own business logic in five areas:

Authentication: Implement adaptive authentication to identify people in one or more steps.

Authorization: Express your policies in Python or Java, or call and external entitlements management system, like XACML or SiteMinder.

Attribute Transformation: Create new attributes, change attribute names, or change the value of existing attributes.

Logout: Make sure you logout of any backend services, such as an external IDP or porotal, or SSO environment.

ID Generation: People don’t see their internal id, but domains may want to use one convention or another to provide a “primary key” value to identify an entity (person, client, etc.) UUID’s are the most common, but also used is IPv6 addresses, DNS style names, or custom schemes.

Authentication Script


public interface ExternalAuthenticatorType {

public boolean init(Map configurationAttributes);

public boolean authenticate(Map configurationAttributes, Map requestParameters, int step);

public boolean prepareForStep(Map configurationAttributes, Map requestParameters, int step);

public int getCountAuthenticationSteps(Map configurationAttributes);

public String getPageForStep(Map configurationAttributes, int step);

public List getExtraParametersForStep(Map configurationAttributes, int step);

Sample Script

from org.jboss.seam.security import Identity
from org.xdi.oxauth.service.python.interfaces import ExternalAuthenticatorType
from org.xdi.oxauth.service import UserService
from org.xdi.util import StringHelper

import java

class ExternalAuthenticator(ExternalAuthenticatorType):
def __init__(self, currentTimeMillis):
self.currentTimeMillis = currentTimeMillis

def init(self, configurationAttributes):
return True

def authenticate(self, configurationAttributes, requestParameters, step):
if (step == 1):
print “Basic authenticate for step 1”

credentials = Identity.instance().getCredentials()
user_name = credentials.getUsername()
user_password = credentials.getPassword()

logged_in = False
if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
userService = UserService.instance()
logged_in = userService.authenticate(user_name, user_password)

if (not logged_in):
return False
# Commented out becuase we do the same in AuthenticationService.authenticate method
# user = userService.getUser(user_name)
# if (user == None):
# print “Basic authenticate for step 1. Failed to find user in local LDAP”
# return False
# # Store user to allow use this module for web services
# credentials.setUser(user);

return True
return False

def prepareForStep(self, configurationAttributes, requestParameters, step):
if (step == 1):
print “Basic prepare for Step 1”
return True
return False

def getExtraParametersForStep(self, configurationAttributes, step):
return None

def getCountAuthenticationSteps(self, configurationAttributes):
return 1

def getPageForStep(self, configurationAttributes, step):
return “”
Attribute Transformation Script

public interface EntryInterceptorType {

public boolean updateAttributes(GluuCustomPerson person);

Sample Attribute Transformation Script

# Import of Java classes
from org.gluu.site.ldap.cache.service.intercept.interfaces import EntryInterceptorType
from org.gluu.site.util import StringHelper
from org.gluu.site.model import GluuCustomPerson
from org.gluu.site.model import GluuCustomAttribute

import java

class EntryInterceptor(EntryInterceptorType):
def __init__(self, currentTimeMillis):
self.currentTimeMillis = currentTimeMillis

def updateAttributes(self, person):

# Assign the current entry’s attributes to an array
attributes = person.getCustomAttributes()

# Create and set the attribute eduPersonPrincipalName
uidValue = person.getAttribute(‘uid’)
attrEPPN = GluuCustomAttribute(‘edupersonprincipalname’, uidValue + ‘@example.edu’)

# Loop through each attribute in the current entry
for attribute in attributes:
attrName = attribute.getName()

# The mapping in the Cache Refresh configuration page set employeeType to
# eduPersonScopedAffiliation(EPSA). This means that EPSA currently has an
# integer value instead of the value expected by Educause. It needs to be
# set to the correct value.
if (“edupersonscopedaffiliation” == StringHelper.toLowerCase(attrName)):
attrValue = attribute.getValue()
newEPSAValue = []

if (attrValue==1):
elif (attrValue==2):
elif (attrValue==3):
elif (attrValue==4):
elif (attrValue==5):

# Remove current attribute which is EPSA with an integer value
epsa = GluuAttribute(‘eduPersonScopedAffiliation’, newEPSAValue)
return True
Authorization Script

public interface IPolicyExternalAuthorization {
public boolean authorize(AuthorizationContext p_authorizationContext);

public interface IAuthorizationContext {
String getClientClaim(String claimName);
String getUserClaim(String claimName);
String getUserClaimByLdapName(String ldapName);
Integer getAuthLevel();
String getAuthMode();
String getIpAddress();
boolean isInNetwork(String cidrNotation);
RequesterPermissionToken getRPT();
ResourceSetPermission getPermission();
AuthorizationGrant getGrant(); // here return unmodifiable version of grant, e.g. to avoid new token creation
HttpServletRequest getHttpRequest();
Python sample authorization script (authorize only if user location claim equals to Austin)

from org.xdi.oxauth.service.uma.authorization import IPolicyExternalAuthorization
from org.xdi.util import StringHelper

class PythonExternalAuthorization(IPolicyExternalAuthorization):

def authorize(self, authorizationContext):

print “authorizing…”

if StringHelper.equalsIgnoreCase(authorizationContext.getUserClaim(“locality”), “Austin”):
print “authorized”
return True

return False


public interface CustomLogoutScript{

* Provides an interception to insert domain specific logic when a person logs out,
* such as logout to backend IDPs.
* @param p_idType id type : use to specify entity type, i.e. person, client
* @return int result code
public String logout(String message);
Sample Script:

import myIDP

class ExampleDomainLogout(CustomLogoutScript):
def logout(self, message):
print “Executing %s” % message
except Exception, err:
print Exception, err
return 1
return 0

public interface IdGenerator {

* Generates id.
* @param p_idType id type : use to specify entity type, i.e. person, client
* @param p_idPrefix id prefix : If you want to prefix all ids, use this, otherwise pass “”
* @return generated id as string
public String generateId(String p_idType, String p_idPrefix);
Sample Script:

import uuid

class ExampleDomainUniqueIdPolicyClass(IdGenerator):
def generateId(self, entityType, prefix):
print “Generating %s ID for prefix %s” % entityType, prefix
# make a UUID using an MD5 hash of a namespace UUID and a name
id = uuid.uuid3(uuid.NAMESPACE_DNS, ‘example.co’)
return “%s%s” % (prefix, id)

Article Source – http://www.gluu.org/blog/five-interceptions-of-the-ox-op/