/// <summary> /// Handles the selection of an IDP. If only one IDP is found, the user is automatically redirected to it. /// If several are found, and nothing indicates to which one the user should be sent, this method returns null. /// </summary> /// <param name="context">The context.</param> /// <param name="config">Configuration. If null, configuration will be populated from application config</param> /// <returns>The <see cref="IdentityProvider"/>.</returns> public IdentityProvider RetrieveIDP(NameValueCollection allparams, NameValueCollection queryString, Saml2Configuration config, Action <string> redirectToSelection) { // If idpChoice is set, use it value if (!string.IsNullOrEmpty(allparams[IdpChoiceParameterName])) { logger.DebugFormat(TraceMessages.IdentityProviderRetreivedFromQueryString, allparams[IdpChoiceParameterName]); var endPoint = config.IdentityProvidersSource.GetById(allparams[IdpChoiceParameterName]); if (endPoint != null) { return(endPoint); } } // If we have a common domain cookie, use it's value // It must have been returned from the local common domain cookie reader endpoint. if (!string.IsNullOrEmpty(queryString["_saml_idp"])) { var cdc = new Protocol.CommonDomainCookie(queryString["_saml_idp"]); if (cdc.IsSet) { var endPoint = config.IdentityProvidersSource.GetById(cdc.PreferredIDP); if (endPoint != null) { logger.DebugFormat(TraceMessages.IdentityProviderRetreivedFromCommonDomainCookie, cdc.PreferredIDP); return(endPoint); } logger.WarnFormat(ErrorMessages.CommonDomainCookieIdentityProviderInvalid, cdc.PreferredIDP); } } // If there is only one configured IdentityProviderEndpointElement lets just use that if (config.IdentityProvidersSource.GetAll().Any()) { var idp = config.IdentityProvidersSource.GetAll().First(); logger.DebugFormat(TraceMessages.IdentityProviderRetreivedFromDefault, idp.Name); return(idp); } // If one of the endpoints are marked with default, use that one var defaultIDP = config.IdentityProvidersSource.GetAll().FirstOrDefault(idp => idp.Default); if (defaultIDP != null) { logger.DebugFormat(TraceMessages.IdentityProviderRetreivedFromDefault, defaultIDP.Id); return(defaultIDP); } // In case an IDP selection url has been configured, redirect to that one. if (!string.IsNullOrEmpty(config.IdentityProvidersSource.SelectionUrl)) { logger.DebugFormat(TraceMessages.IdentityProviderRetreivedFromSelection, config.IdentityProvidersSource.SelectionUrl); redirectToSelection(config.IdentityProvidersSource.SelectionUrl); return(null); } // If an IDPSelectionEvent handler is present, request the handler for an IDP endpoint to use. return(IdpSelectionUtil.InvokeIDPSelectionEventHandler(config.IdentityProvidersSource)); }
/// <summary> /// Send an authentication request to the IDP. /// </summary> /// <param name="context">The context.</param> private void SendRequest(HttpContext context, Saml2Configuration config) { // See if the "ReturnUrl" - parameter is set. var returnUrl = context.Request.QueryString["ReturnUrl"]; if (!string.IsNullOrEmpty(returnUrl) && context.Session != null) { context.Session["RedirectUrl"] = returnUrl; } var isRedirected = false; var selectionUtil = new IdpSelectionUtil(Logger); var idp = selectionUtil.RetrieveIDP(context.Request.Params, context.Request.QueryString, config, s => { context.Response.Redirect(s); isRedirected = true; }); if (isRedirected) return; if (idp == null) { // Display a page to the user where she can pick the IDP Logger.DebugFormat(TraceMessages.IdentityProviderRedirect); var page = new SelectSaml20IDP(); page.ProcessRequest(context); return; } var authnRequest = Saml20AuthnRequest.GetDefault(config); TransferClient(idp, authnRequest, context, config); }
public override string BuildRedirectUrl() { string rc = null; var logger = SAML2.Logging.LoggerProvider.LoggerFor(typeof(SamlMessage)); var selectionUtil = new IdpSelectionUtil(logger); var allparams = BuildParams(form, context.Request.Query); var idp = selectionUtil.RetrieveIDP(allparams, BuildParams(context.Request.Query), config, s => rc = s); if (rc != null) return rc; // IDP selection screen if (idp == null) { // Display a page to the user where she can pick the IDP logger.DebugFormat(TraceMessages.IdentityProviderRedirect); throw new NotImplementedException("Selection of IDP not yet done (probably need a map call on middleware extension method)"); //var page = new SelectSaml20IDP(); //page.ProcessRequest(context); //return; } var authnRequest = Saml20AuthnRequest.GetDefault(config); return AuthnRequestForIdp(idp, authnRequest, context, config); }