Exchanging SAML2 bearer tokens with OAuth2 (SAML extension grant type)
SAML 2.0 is an XML-based protocol. It uses security tokens containing assertions to pass information about an enduser between a SAML authority and a SAML consumer.
A SAML authority is an identity provider (IDP) and a SAML consumer is a service provider (SP).
A lot of enterprise applications use SAML2 to engage a third-party identity provider to grant access to systems that are only authenticated against the enterprise application.
These enterprise applications might need to consume OAuth-protected resources through APIs, after validating them against an OAuth2.0 authentication server.
However, an enterprise application that already has a working SAML2.0 based SSO infrastructure between itself and the IDP prefers to use the existing trust relationship, even if the OAuth authorization server is entirely different from the IDP. The SAML2 Bearer Assertion Profile for OAuth2.0 helps leverage this existing trust relationship by presenting the SAML2.0 token to the authorization server and exchanging it to an OAuth2.0 access token.
You can use SAML grant type for web applications to generate tokens.
https://docs.wso2.com/display/AM160/Token+API#TokenAPI-ExchangingSAML2bearertokenswithOAuth2(SAMLextensiongranttype)
Sample curl command .
curl -k -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=&scope=PRODUCTION" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh, Content-Type: application/x-www-form-urlencoded" https://serverurl/token
How to invoke token API from web app and get token programmatically.
To generate user access token using SAML assertion you can add following code block inside your web application.
When you login to your app using SSO there would be access you will get SAML response. You can store that in application session and use it to get token whenever requires.
Please refer following code for Access token issuer.
package com.test.org.oauth2;
import org.apache.amber.oauth2.client.OAuthClient;
import org.apache.amber.oauth2.client.URLConnectionClient;
import org.apache.amber.oauth2.client.request.OAuthClientRequest;
import org.apache.amber.oauth2.common.token.OAuthToken;
import org.apache.catalina.Session;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AccessTokenIssuer {
private static Log log = LogFactory.getLog(AccessTokenIssuer.class);
private Session session;
private static OAuthClient oAuthClient;
public static void init() {
if (oAuthClient == null) {
oAuthClient = new OAuthClient(new URLConnectionClient());
}
}
public AccessTokenIssuer(Session session) {
init();
this.session = session;
}
public String getAccessToken(String consumerKey, String consumerSecret, GrantType grantType)
throws Exception {
OAuthToken oAuthToken = null;
if (session == null) {
throw new Exception("Session object is null");
}
// You need to implement logic for this operation according to your system design. some url
String oAuthTokenEndPoint = "token end point url"
if (oAuthTokenEndPoint == null) {
throw new Exception("OAuthTokenEndPoint is not set properly in digital_airline.xml");
}
String assertion = "";
if (grantType == GrantType.SAML20_BEARER_ASSERTION) {
// You need to implement logic for this operation according to your system design
String samlResponse = "get SAML response from session";
// You need to implement logic for this operation according to your system design
assertion = "get assertion from SAML response";
}
OAuthClientRequest accessRequest = OAuthClientRequest.
tokenLocation(oAuthTokenEndPoint)
.setGrantType(getAmberGrantType(grantType))
.setClientId(consumerKey)
.setClientSecret(consumerSecret)
.setAssertion(assertion)
.buildBodyMessage();
oAuthToken = oAuthClient.accessToken(accessRequest).getOAuthToken();
session.getSession().setAttribute("OAUTH_TOKEN" , oAuthToken);
session.getSession().setAttribute("LAST_ACCESSED_TIME" , System.currentTimeMillis());
return oAuthToken.getAccessToken();
}
private static org.apache.amber.oauth2.common.message.types.GrantType getAmberGrantType(
GrantType grantType) {
if (grantType == GrantType.SAML20_BEARER_ASSERTION) {
return org.apache.amber.oauth2.common.message.types.GrantType.SAML20_BEARER_ASSERTION;
} else if (grantType == GrantType.CLIENT_CREDENTIALS) {
return org.apache.amber.oauth2.common.message.types.GrantType.CLIENT_CREDENTIALS;
} else if (grantType == GrantType.REFRESH_TOKEN) {
return org.apache.amber.oauth2.common.message.types.GrantType.REFRESH_TOKEN;
} else {
return org.apache.amber.oauth2.common.message.types.GrantType.PASSWORD;
}
}
}
After you login to system get session object and initiate access token issuer as follows.
AccessTokenIssuer accessTokenIssuer = new AccessTokenIssuer(session);
Then keep reference for that object during session.
Then when you need access token request token as follows. You need to pass consumer key and secret key.
tokenResponse = accessTokenIssuer.getAccessToken(key,secret, GrantType.SAML20_BEARER_ASSERTION);
Then you will get access token and you can use it as required.