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


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:


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

  • Sample SAML request XML
  • <?xml version="1.0" encoding="UTF-8"?> <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="dfqeyfbencoiwejdwomwe" Version="2.0" IssueInstant="2014-07-07T12:06:15.889Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" AssertionConsumerServiceURL=""> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> </saml:Issuer> </samlp:AuthnRequest>

    You can use OpenSAML open source library to create this request.

  • Maven dependency for OpenSAML

  • <dependency> <groupId>org.opensaml</groupId> <artifactId>opensaml</artifactId> <version>2.6.1</version> </dependency>

    Or you can download OpenSAML open source library JAR from:

  • Sample Java Code for creating the SAML request using OpenSAML library

  • import; import; import; import; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import; import org.apache.commons.codec.binary.Base64; import org.opensaml.Configuration; import org.opensaml.DefaultBootstrap; import org.opensaml.common.SAMLObjectBuilder; import org.opensaml.common.SAMLVersion; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.saml2.core.Issuer; import org.opensaml.xml.XMLObject; import; import; import org.w3c.dom.Element; public String generateSAMLRequest() { DefaultBootstrap.bootstrap(); AuthnRequest request = ((SAMLObjectBuilder)
    Configuration.getBuilderFactory().getBuilder( AuthnRequest.DEFAULT_ELEMENT_NAME)).buildObject(); /* Your consumer URL (where you want to receive SAML response) */ request.setAssertionConsumerServiceURL(""); /* Unique request ID */ request.setID("reg-123"); request.setVersion(SAMLVersion.VERSION_20); request.setIssueInstant(new org.joda.time.DateTime()); request.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); /* Your issuer URL */ request.setIssuer(buildIssuer("")); /* Setting jsonRequestString as StringEntity */ String base64EncodedRequest = base64EncodeXMLObject(request); return base64EncodedRequest; } private Issuer buildIssuer(String issuerValue) { Issuer issuer = ((SAMLObjectBuilder) Configuration.getBuilderFactory().getBuilder( Issuer.DEFAULT_ELEMENT_NAME)).buildObject(); issuer.setValue(issuerValue); return issuer; } private Issuer base64EncodeXMLObject(XMLObject xmlObject) { MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); Element samlObjectElement = marshaller.marshall(xmlObject); // Transforming Element into String Transformer transformer = TransformerFactory.newInstance().newTransformer(); StreamResult result = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(samlObjectElement); transformer.transform(source, result); String xmlString = result.getWriter().toString(); /* first DEFLATE compress the document (saml-bindings-2.0, section */ byte[] xmlBytes = xmlString.getBytes("UTF-8"); ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteOutputStream); deflaterOutputStream.write(xmlBytes, 0, xmlBytes.length); deflaterOutputStream.close(); // next, base64 encode it Base64 base64Encoder = new Base64(); byte[] base64EncodedByteArray = base64Encoder.encode(byteOutputStream.toByteArray()); String base64EncodedMessage = new String(base64EncodedByteArray); // finally, URL encode it String urlEncodedMessage = URLEncoder.encode(base64EncodedMessage, "UTF-8"); return urlEncodedMessage; }

  • Submit this request to miniOrange SSO Service

  • <html><head><script> window.onload = function() { document.forms['saml-form'].submit(); } </script></head>
    <form id="saml-form" method="get" action="[identity_provider_url]">
    <input type="hidden" name="SAMLRequest" value="generated-request" />
    <input type="hidden" name="RelayState" value="" />

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; import; import; import; import; 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; import org.opensaml.xml.XMLObject; import; import; import; import; 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":"","primaryPhone":"+917XXXXXXX", "email":"","name":"Demo User","family_name":"User", "preferred_username":"","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.

  • Discovery End point Service: Contains URL and information of all the endpoint's mentioned below including path to JSON JWK set.


  • Authorization endpoint:

    The authorisation endpoint is the only one where the end-user interacts with the OpenID Connect provider. The other endpoints are meant for handling direct back - channel requests from the client application.

    Request params : client_id, scope, redirect_uri, response_type, state.

    Client_id : Unique client identifier

    Scope: Kind of information required for a particular user.

    Redirect_uri : https endpoint to which the user should be returned.

    Reponse : code, state

    Sample Request: http://localhost:8080/moas/idp/openidsso?response_type=code&client_id=Anzjx4Sf3aVe6gg& redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsampleapp%2Foidcresponse&scope=openid+email+profile &state=yAwL-57K10sIIpGeVO7nR7ZAnzdsj01uGothExyVpmo&nonce=ayLpTaFf-YzqtX3Jq_lTSKJmc7AUh5ELNwoIRs1XPmc Sample Response: code: kuwbrec8_sacca state: yAwL-57K10sIIpGeVO7nR7ZAnzdsj01uGothExyVpmo

  • Token End point Service:

    The token endpoint authenticates the client application, then lets it exchange the code received from the authorisation endpoint for an ID token and access token.

    Token uri from discovery endpoint

    Request params : code, state

    Request Type: POST

    Response : token (JSON)

  • Userinfo Service:

    The UserInfo endpoint is an OAuth 2.0 protected HTTPS resource for which an access token is required. The UserInfo endpoint returns consented profile information to the client application. This information is intended to facilitate user provisioning.

    URL : userinfo uri from discovery endpoint

    Request params : Header : Bearer {access_token}

    Request Type: POST

    Response : user_info (JSON)

  • Provider JWK Set Endpoint

    The JWK endpoint contains keys to sign and validate the id_token on server and client side respectively.

    URL : Jwk set uri from Discovery endpoint

    Request Type: POST

    Response : JWK set (JSON)

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:

  • commons-httpclient 3.1
  • commons-lang3-3.4
  • commons-logging-1.1.2
  • guava-12.0.1
  • httpclient-4.1.1
  • http-core-4.1
  • json20090211