Single Sign On API Guide
A guide on how to use miniOrange Single Sign On APIs.

Overview

Single Sign-On (SSO) removes the need to repeatedly type usernames and passwords, which increases productivity and prevents many types of online fraud that is caused by using same or similar passwords across apps, tying in passwords in un-safe environments, password sharing etc.

miniOrange Single Sign-On APIs allows you to integrate sso quickly and secure access to your applications.

We support Single Sign-On APIs for:

Pre-requisites

Steps to integrate miniOrange Single Sign on API for SAML

Step 1: Create a SAML request and send it to miniOrange SSO service

You need to create SAML request and send it as a GET parameter : Contact Us for url



Step 2: Receiving SAML response and validating signature

After successful login you will receive the SAML response containing username and signature. The username is contained in the NameIdentifier element of the Subject statement.


NOTE: It is recommended that you verify our signature before signing in the user to your application.
Sample Java Code for reading SAML Response:

import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.codec.binary.Base64; import org.opensaml.Configuration; import org.opensaml.DefaultBootstrap; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.core.Subject; import org.opensaml.security.SAMLSignatureProfileValidator; import org.opensaml.xml.XMLObject; import org.opensaml.xml.io.Unmarshaller; import org.opensaml.xml.io.UnmarshallerFactory; import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.security.x509.BasicX509Credential; import org.opensaml.xml.signature.SignatureValidator; import org.w3c.dom.Document; import org.w3c.dom.Element;
public String receiveSAMLResponse() { /* Getting the response string from HTTP Request object */ String responseString = (String) httpRequest.getParameter("SAMLResponse"); /* Decoding Base64 response string to get the XML string */ String responseXml = new String(Base64.decodeBase64(responseString), "UTF-8"); /* Generating SAML Response object from XML string */ DefaultBootstrap.bootstrap(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); ByteArrayInputStream is = new ByteArrayInputStream(responseXml.getBytes()); Document document = docBuilder.parse(is); Element element = document.getDocumentElement(); UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element); XMLObject xmlObj = unmarshaller.unmarshall(element); Response response = (Response) xmlObj; /* Validating the signature on the response */ validateSignature(response); /* If validation was successful, get the username from the response. */ Subject subject = response.getAssertions().get(0).getSubject(); String username = subject.getNameID().getValue(); return username; } private void validateSignature(Response response) { SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); try { profileValidator.validate(response.getSignature()); } catch (ValidationException e) { /* Indicates signature did not conform to SAML Signature profile */ e.printStackTrace(); throw e; } Credential verificationCredential = getVerificationCredential(); SignatureValidator sigValidator = new SignatureValidator(verificationCredential); try { sigValidator.validate(response.getSignature()); } catch (ValidationException e) { /* Indicates signature was not cryptographically valid, or possibly a processing error. */ e.printStackTrace(); throw e; } } private Credential getVerificationCredential() { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("/pathToYourCertificte")); CertificateFactory cf = CertificateFactory.getInstance("X509"); X509Certificate cert = (X509Certificate)cf.generateCertificate(bis); BasicX509Credential x509Credential = new BasicX509Credential(); x509Credential.setPublicKey(cert.getPublicKey()); x509Credential.setEntityCertificate(cert); Credential credential = x509Credential; return credential; }

Steps to integrate miniOrange Single Sign on API for OpenID Connect

Step 1: Create a REST service or similar on your application to handle response from Authorization Endpoint(Note : this must be the redirect URI parameter).

Example (https://<your-domain>/rest/openidresponse)

Response attributes: code ,state.

Now you just need to make two calls: one to get access token and another to get user info with the help of that access_token.

//Import our miniOrange API(copy all the JAR files in a lib folder and add them to build path) //Step 1 : Make a token request using code and state parameter received on the redirect uri. String token = AuthServerRequest.sendTokenRequest(code, state); /** Example string token JSON : {"scope":"openid","expires_in":3600,"token_type":"bearer", "id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEifQ.eyJhdXRoX3RpbWUiOiJUaHUgQXBy IDE2IDEzOjA2OjE4IElTVCAyMDE1IiwiZXhwIjoxNDMwMTY5Nzc4LCJzdWIiOiJkZW1vQG1pbmlvcmFuZ2UuY28uaW4iLCJub25jZSI6IkJ1U1 MxSjktZllmaDgwYmVDOVdwM2Vwc1BCdHRpLVdmS09xdGlmWnMxa0UiLCJhdF9oYXNoIjoiMmY2ZnlqWGRRUmdWVTl3IiwiYXVkIjpbIkFuemp4 NFNmM2FWZTZnZyJdLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3QiLCJpYXQiOjE0MjkxNjk3Nzh9.P6VXffhTX9B62tjupP8tWdv9eYpXCBnDt ramHDDF2pYujcgNPntX1OrEieD1Uvswdk2qagOfm0HbfG3OtGa6xZ8Ixpqg7RDUusPRHFptcgSw9YlZtyv1CyIIh_eQ4yrfo2oHfwW-5aDIUO5 tNmjoWrEK4NzR1fWYXRmL5eyu51o", "access_token":"2f6fyjXdQRgVU9w"} **/ //Step 2 : OPTIONAL. Validate id_token on your side. <Your java code for validating id_token from the JWK set> //Step 3: Make a user_info request. Fetch access_token from the JSON string token received in Step 1. String user_info = AuthServerRequest.sendUserInfoRequest(access_token); /** Example user info JSON : {"sub":"demo@miniorange.co.in","primaryPhone":"+917XXXXXXX", "email":"demo@miniorange.co.in","name":"Demo User","family_name":"User", "preferred_username":"demo@miniorange.co.in","given_name":"Demo"} **/ Return user_info; //Proceed your login flow with the user_info scopes.

token is a JSON which contains the following attributes:

Field Description
access_token OAuth 2.0 Access Token. This is returned from the token endpoint
token_type OAuth 2.0 Token Type value. The value MUST be Bearer or another token_type value that the Client has negotiated with the Authorization Server. Clients implementing this profile MUST support the OAuth 2.0 Bearer Token Usage [RFC6750] specification. This profile only describes the use of bearer tokens. This is returned in the same cases as access_token is.
expired_in OPTIONAL. Expiration time of the Access Token in seconds since the response was generated.
scope scope parameter value : openid
id_token Contains a JSON of fieldset iss, sub ,aud, nonce, exp, iat, auth_time, at_hash

id_token contains the following JSON attributes:

Field Description
iss https URI that indicates the issuer
sub identifier of the user at the issuer
aud client_id of the requesting client
nonce the nonce parameter value received from the client
exp expiration time of this token
iat time when this token was issued
auth_time time the authentication happened
at_hash the first half of a hash of the access token

User info is a JSON which contains the following attributes:

Field Description
Email Email of the user
Phone Contact number of the user
Name Full name of the user

Once you have the user info JSON. You can initiate your login by passing the email/username information to your local authentication functionality.

Endpoints Explained.

If you wish to use any third party client libraries. Or if want to write your own client, than you can use our Endpoint's directly to authenticate user in your website or application.


miniOrange OpenID Connect Client Library Documentation for Java:

miniOrange client library can be used to request/make calls to our token endpoint and user info endpoint.

Token endpoint:

Request : code, state.

Response : token JSON: { 'aud': xxx, 'sub': xxx, 'iss': xxx, 'exp' : xxx, 'access_token': xxx }

User info endpoint:

Request: access_token

Response : userinfo JSON {'name' : xxx, 'email' : xxx , 'primaryPhone' : xxx }

1. Calling token endpoint.

token = AuthorizationServerRequest.sendTokenRequest(code, state);

2. Calling user info endpoint.

user_info = authorizationServerRequest.sendUserInfoRequest(access_token);

Token and user_info are the JSON objects containing access_token and user information respectively.


Libraries JAR :

Main library: miniorange-openid-api

Assisting libraries required: