Azure AD, bypassing home realm discovery

michaeldeutsch
Kilo Expert

Has anyone been able to bypass the Azure Home realm Discovery (The page that requires an email address to redirect to proper tenant) when using ServiceNow that authenticates to Azure Active Directory.

See link for information as to what I am talking about. Skipping the Home Realm Discovery Page in Azure AD | CloudIdentity

3 REPLIES 3

jonathan_cook
Kilo Explorer

I have the same question. We are looking at implementing AzureAD signon and the main hesitation now is the extra login screen (even if it is mostly the first time you login) since end users will not be used to seeing it.


If there is any way to set the Scoping attribute to bypass the screen and enable fully automated signon (for a single domain) that would be great.


https://blogs.technet.microsoft.com/enterprisemobility/2015/02/11/using-azure-ad-to-land-users-on-th...


benanderson
Tera Contributor

Hey guys,



This is indeed possible. You will need to contact Hi Support to get the following Java packages whitelisted on your instance:



Packages.org.opensaml.saml2.core.impl.ScopingBuilder


Packages.org.opensaml.saml2.core.impl.ScopingMarshaller


Packages.org.opensaml.saml2.core.impl.IDPListBuilder


Packages.org.opensaml.saml2.core.impl.IDPListMarshaller


Packages.org.opensaml.saml2.core.impl.IDPEntryBuilder


Packages.org.opensaml.saml2.core.impl.IDPEntryMarshaller



The instance will need to be restarted after the whitelisting has occurred. After that, you can make the following changes to the script include SAML2_update1:



Replace createAuthnRequestWithOptions with below:



createAuthnRequestWithOptions : function(samlOptions) {


  var DateTime = Packages.org.joda.time.DateTime;


  var SAMLVersion = Packages.org.opensaml.common.SAMLVersion;


  var AuthnRequestBuilder = Packages.org.opensaml.saml2.core.impl.AuthnRequestBuilder;


  var AuthnRequestMarshaller = Packages.org.opensaml.saml2.core.impl.AuthnRequestMarshaller;


  var Boolean = Packages.java.lang.Boolean;


  // Retrieve Default value


  var serviceURL = this.ssoHelper.getProperty("glide.authenticate.sso.saml2.service_url", "service_url");


  var providerName = serviceURL;


  var forceAuthn = this.isTrue(this.ssoHelper.getProperty("glide.authenticate.sso.saml2.defaults.force_authn", "force_authn", false));


  var isPassive = this.isTrue(this.ssoHelper.getProperty("glide.authenticate.sso.saml2.defaults.is_passive", "is_passive", false));


  var assertionConsumerServiceURL = serviceURL;


  var protocolBinding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";


  if (samlOptions && samlOptions.providerName)


  providerName = samlOptions.providerName;


  if (samlOptions && samlOptions.forceAuthn)


  forceAuthn = new Boolean(samlOptions.forceAuthn);


  if (samlOptions && samlOptions.isPassive)


  isPassive = new Boolean(samlOptions.isPassive);


  if (samlOptions && samlOptions.assertionConsumerServiceURL)


  assertionConsumerServiceURL = samlOptions.assertionConsumerServiceURL;


  //for later validation


  gs.getSession().getHttpSession().setAttribute("glide.saml2.assertion_consumer_service_url", assertionConsumerServiceURL);


  var builder = new AuthnRequestBuilder();


  var authnRequest = builder.buildObject();


  authnRequest.setProviderName(providerName);


  authnRequest.setID(this.generateRequestID());


  authnRequest.setVersion(SAMLVersion.VERSION_20);


  authnRequest.setIssueInstant(new DateTime());


  authnRequest.setForceAuthn(forceAuthn);


  authnRequest.setIsPassive(isPassive);


  authnRequest.setAssertionConsumerServiceURL(assertionConsumerServiceURL);


  authnRequest.setProtocolBinding(protocolBinding);


  authnRequest.setIssuer(this.createIssuer());


  authnRequest.setNameIDPolicy(this.createNameIDPolicy());


  authnRequest.setDestination(this.ssoHelper.getProperty("glide.authenticate.sso.saml2.idp_authnrequest_url", "idp_authnrequest_url"));


  var createAuthnContextClassRef = this.isTrue(this.ssoHelper.getProperty("glide.authenticate.sso.saml2.createrequestedauthncontext", "createrequestedauthncontext", true));


  if (createAuthnContextClassRef) {


  authnRequest.setRequestedAuthnContext(this.createRequestedAuthnContext());


  }


  this.createScoping(authnRequest);


  return authnRequest;


  },



Add a new function for the scoping createScoping and replace the domain hint below with whatever is valid for you. I've also just referenced the correct property for the Provider ID, since it is already being used elsewhere.



  createScoping : function (authnRequest) {


  var ScopingBuilder = Packages.org.opensaml.saml2.core.impl.ScopingBuilder;


  var ScopingMarshaller = Packages.org.opensaml.saml2.core.impl.ScopingMarshaller;


  var IDPListBuilder = Packages.org.opensaml.saml2.core.impl.IDPListBuilder;


  var IDPListMarshaller = Packages.org.opensaml.saml2.core.impl.IDPListMarshaller;


  var IDPEntryBuilder = Packages.org.opensaml.saml2.core.impl.IDPEntryBuilder;


  var IDPEntryMarshaller = Packages.org.opensaml.saml2.core.impl.IDPEntryMarshaller;


  var idpListBuilder = new IDPListBuilder();


  var idpList = idpListBuilder.buildObject();


  var idpEntryBuilder = new IDPEntryBuilder();


  var idp = idpEntryBuilder.buildObject();


  idp.setName("<domain hint>");


  idp.setProviderID(this.propertiesGR.getValue('idp'));


  var listEntry = idpList.getIDPEntrys();


  listEntry.add(idp);


  var scopingBuilder = new ScopingBuilder();


  var scoping = scopingBuilder.buildObject();


  scoping.setIDPList(idpList);


  authnRequest.setScoping(scoping);



  },



Enjoy bypassing the Azure login screen


benanderson


Thanks for this!



We got SN to get things whitelisted, but they aren't able to provide clarification on what is required in idp.setName and idp.setProviderID. We have had Azure integrate into our ServiceNow, which set up a new SAML2 based identity provider.



Would the idp.setName simply be our domain name with Azure, such as contoso.ca?


Would the idp.setProviderID be our "Identity Provider URL" from our SAML2 identity provider that Azure set up in our instance? I see you put in "this.propertiesGR.getValue('idp')" but our sys property of "idp" is the out of box "http://idp.ssocircle.com/ " and not related to our new SAML2 idp from Azure.



Thank you.