// Create an authentication request. private XmlElement CreateAuthnRequest() { // Create some URLs to identify the service provider to the identity provider. // As we're using the same endpoint for the different bindings, add a query string parameter // to identify the binding. string issuerURL = CreateAbsoluteURL("~/"); string assertionConsumerServiceURL = CreateAssertionConsumerServiceURL(); // Create the authentication request. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Destination = WebConfigurationManager.AppSettings["idpssoURL"]; authnRequest.Issuer = new Issuer(issuerURL); authnRequest.ForceAuthn = false; authnRequest.NameIDPolicy = new NameIDPolicy(null, null, true); authnRequest.ProtocolBinding = idpToSPBindingRadioButtonList.SelectedValue; authnRequest.AssertionConsumerServiceURL = assertionConsumerServiceURL; // Serialize the authentication request to XML for transmission. XmlElement authnRequestXml = authnRequest.ToXml(); // Don't sign if using HTTP redirect as the generated query string is too long for most browsers. if (spToIdPBindingRadioButtonList.SelectedValue != SAMLIdentifiers.BindingURIs.HTTPRedirect) { // Sign the authentication request. X509Certificate2 x509Certificate = (X509Certificate2) Application[Global.SPX509Certificate]; SAMLMessageSignature.Generate(authnRequestXml, x509Certificate.PrivateKey, x509Certificate); } return authnRequestXml; }
/// <summary> /// This Post Action is used to Generate the AuthN Request and redirect to the B2C Login endpoint /// </summary> public IActionResult OnPost(string Tenant, string HostName, string Policy, string Issuer, string DCInfo, bool IsAzureAD) { if (string.IsNullOrEmpty(Policy) || IsAzureAD) { return(SendAzureAdRequest(Tenant)); } string SamlRequest = string.Empty; string b2cloginurl = HostName.ToLower(); if (!String.IsNullOrEmpty(HostName)) { b2cloginurl = HostName; } else if (!String.IsNullOrEmpty(this.Tenant) && this.Tenant.EndsWith(".onmicrosoft.com")) { string TenantName = Tenant.ToLower()?.Replace(".onmicrosoft.com", ""); b2cloginurl = TenantName + ".b2clogin.com"; } Policy = Policy.StartsWith("B2C_1A_") ? Policy : "B2C_1A_" + Policy; //Tenant = (Tenant.ToLower().Contains("onmicrosoft.com") || Tenant.ToLower().Contains(".net")) ? Tenant : Tenant + ".onmicrosoft.com"; DCInfo = string.IsNullOrWhiteSpace(DCInfo) ? string.Empty : "&" + DCInfo; Issuer = string.IsNullOrWhiteSpace(Issuer) ? SAMLHelper.GetThisURL(this) : Issuer; if (null != Tenant) { HttpContext.Session.SetString("Tenant", Tenant); } if (null != b2cloginurl) { HttpContext.Session.SetString("HostName", b2cloginurl); } if (null != Policy) { HttpContext.Session.SetString("Policy", Policy); } if (null != Issuer) { HttpContext.Session.SetString("Issuer", Issuer); } string RelayState = SAMLHelper.toB64(Tenant) + "." + SAMLHelper.toB64(Policy) + "." + SAMLHelper.toB64(Issuer); if (!string.IsNullOrEmpty(DCInfo)) { RelayState = RelayState + "." + SAMLHelper.toB64(DCInfo); } AuthnRequest AuthnReq; string URL = "https://" + b2cloginurl + "/" + Tenant + "/" + Policy + "/samlp/sso/login?" + DCInfo; AuthnReq = new AuthnRequest(URL, SAMLHelper.GetThisURL(this), Issuer); string cdoc = SAMLHelper.Compress(AuthnReq.ToString()); URL = URL + "&SAMLRequest=" + System.Web.HttpUtility.UrlEncode(cdoc) + "&RelayState=" + System.Web.HttpUtility.UrlEncode(RelayState); return(Redirect(URL)); }
protected override void BuildInternal(AuthnRequest request, AuthnRequestConfiguration configuration) { request.Issuer = new NameId { Value = configuration.EntityId, Format = NameIdentifierFormats.Entity }; }
/// <summary> /// Initializes a new instance of the <see cref="Saml20AuthnRequest"/> class. /// </summary> public Saml20AuthnRequest() { request = new AuthnRequest(); request.Version = Saml20Constants.Version; request.ID = "id" + Guid.NewGuid().ToString("N"); request.Issuer = new NameID(); request.IssueInstant = DateTime.Now; }
public IActionResult SendAzureAdRequest() { var AuthnReq = new AuthnRequest("https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/saml2", SAMLHelper.GetThisURL(this), string.Empty); var cdoc = SAMLHelper.Compress(AuthnReq.ToString()); var URL = $"https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/saml2?SAMLRequest=" + System.Web.HttpUtility.UrlEncode(cdoc); return(Redirect(URL)); }
//private readonly IStoreSamlCertificates _certificates; //public Test(IStoreSamlCertificates certificatesStore) //{ // _certificates = certificatesStore; //} //private X509Certificate2 GetCertificate() //{ // var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); // try // { // //< add key = "SamlTestServiceProviderEntityId" value = "https://develop.ucosmic.com/sign-on/saml/2" /> // //< add key = "SamlTestCertificateThumbprint" value = "1945D599DF7F3B3D6513C87A8CDDF4CE6E0899B6" /> // store.Open(OpenFlags.ReadOnly); // var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, "1945D599DF7F3B3D6513C87A8CDDF4CE6E0899B6", false); // if (certificates.Count < 1) // { // throw new InvalidOperationException(string.Format( // "Could not find certificate with thumbprint '{0}' in My LocalMachine store.", // "1945D599DF7F3B3D6513C87A8CDDF4CE6E0899B6")); // } // return certificates[0]; // } // finally // { // store.Close(); // } //} public void SendAuthnRequest(string idpLocation, Saml2SsoBinding idpBinding, string fromSpEntityId, string returnUrl, HttpContextBase httpContext) { // Create the authentication request. var authnRequest = new AuthnRequest { Destination = idpLocation, Issuer = new Issuer(fromSpEntityId), ForceAuthn = true, NameIDPolicy = new NameIDPolicy(null, null, true), }; // Serialize the authentication request to XML for transmission. var authnRequestXml = authnRequest.ToXml(); // Don't sign if using HTTP redirect as the generated query string is too long for most browsers. //if (idpBinding != Saml2SsoBinding.HttpRedirect) //{ // // Sign the authentication request. // var signingCertificate = _certificates.GetSigningCertificate(); // SAMLMessageSignature.Generate(authnRequestXml, signingCertificate.PrivateKey, signingCertificate); //} // Create and cache the relay state so we remember which SP resource the user wishes to access after SSO. //SAML.HttpContext = httpContext; string relayState = null; if (!string.IsNullOrWhiteSpace(returnUrl)) { relayState = RelayStateCache.Add(new RelayState(returnUrl, null)); } var privateKey = @"MIIDUDCCAjgCCQDZl9Be7/58pTANBgkqhkiG9w0BAQsFADBqMQswCQYDVQQGEwJH QjERMA8GA1UECAwIU29tZXJzZXQxDTALBgNVBAcMBEJhdGgxHDAaBgNVBAoME0Jh dGggU3BhIFVuaXZlcnNpdHkxGzAZBgNVBAMMEmF1dGguYmF0aHNwYS5hYy51azAe Fw0xNzA2MTIxMjMxMjNaFw0zNzA2MDcxMjMxMjNaMGoxCzAJBgNVBAYTAkdCMREw DwYDVQQIDAhTb21lcnNldDENMAsGA1UEBwwEQmF0aDEcMBoGA1UECgwTQmF0aCBT cGEgVW5pdmVyc2l0eTEbMBkGA1UEAwwSYXV0aC5iYXRoc3BhLmFjLnVrMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw54yhGaNi9/5YADBiGWn33YcQNAI f6jagUt7uc/XTcTMoHrirLNftACRzhLXS049fwe48EC6xITe5PWNbiglEXyLmnBF KMOCN7dXDCPWKhSe9vBA2b6+2BS22jAi255WhDj65u4j1+Rg5i0r5E/YLwvG5YAw i9aKSHvvwFwy8Gwo7O3viMqlKsIKx+VV3SfC70NhvtCPh1aHbECfXr05kx5KYXnO UZRZHVLdzG9XP1+BawFcY+kFcflK9uNHUD/i36gCO0X2KciwWWHrmI5ZSR4tymUv FYAIiPklFReOqXUgj0v8pS/NqxKrRzZZWPwbTieJBS0GTt6YvCrQZVnzXQIDAQAB MA0GCSqGSIb3DQEBCwUAA4IBAQBO7NZbRXUfdaICB33BuAwOxsaXaSBkEI6tgZLx wAI/gmOEy639DxWGFuhoUeMhl9B3w5COes7VNvgy9Dl/QaZLH9p3pTBwtc92nN2J U3S4MPdGhtXXKud2DiQuGYtTnp48wbphfAGQDKhz6RI3gionZyHBOkV6Fx5XvSVj Oa7DRfawg951TKGP3OpKI4vuY3kb4hW7XEFfcCEQOcaCujckSwxU6QaI7DnDGP+O wdBmfdEj9Ey37nM0qrzI5cjTz51xJ9c0oNd3+abiGzzL7L7N+AfRVcECowo5l63j vNXAI2IiTocKRsZIWg8qn0pFts3vr7afzJMY6ZQsISwD4fLg"; var bytes = privateKey.GetType(); // Send the authentication request to the identity provider over the configured binding. switch (idpBinding) { case Saml2SsoBinding.HttpPost: ServiceProvider.SendAuthnRequestByHTTPPost(httpContext.Response, idpLocation, authnRequestXml, relayState); httpContext.Response.End(); break; case Saml2SsoBinding.HttpRedirect: var encryptionCertificate = new X509Certificate2(); //var encryptionCertificate = GetCertificate(); encryptionCertificate.Import(Encoding.ASCII.GetBytes(privateKey)); ServiceProvider.SendAuthnRequestByHTTPRedirect(httpContext.Response, idpLocation, authnRequestXml, relayState, encryptionCertificate.PrivateKey); break; default: throw new NotSupportedException(string.Format( "The binding is currently not supported.")); } }
/// <summary> /// Initializes a new instance of the <see cref="Saml20AuthnRequest"/> class. /// </summary> public Saml20AuthnRequest() { Request = new AuthnRequest { Version = Saml20Constants.Version, Id = "id" + Guid.NewGuid().ToString("N"), Issuer = new NameId(), IssueInstant = DateTime.Now }; }
protected override void BuildInternal(AuthnRequest request, AuthnRequestConfiguration configuration) { var format = this.ResolveFormat(configuration); request.NameIdPolicy = new NameIdPolicy { AllowCreate = configuration.AllowCreateNameIdPolicy, Format = format }; }
public override async Task InvokeAsync(HttpContext context) { Logger.LogInformation("Initiating SAML2P authentication (IDP flow)."); var id = context.Request.Query[Options.PartnerIdQueryParameter]; if (StringValues.IsNullOrEmpty(id)) { throw new InvalidOperationException($"Missing '{Options.PartnerIdQueryParameter}' query parameter."); } var partner = await Partners.GetServiceProviderAsync(id); if (partner == null) { throw new SecurityException($"Partner '{id}' not found."); } if (!partner.Enabled) { throw new SecurityException($"Partner '{id}' is disabled."); } if (!partner.AllowsIdpInitiatedSso) { throw new SecurityException($"IDP initiated SSO is not allowed for partner '{id}'."); } var request = new AuthnRequest { AssertionConsumerServiceUrl = new Uri(partner.BaseUrl, partner.AssertionConsumerServiceEndpoint), Issuer = partner.Id }; Trace("Generated SAMLRequest.", request); var key = $"idp_initiated_{Guid.NewGuid().ToString()}"; await Cache.CacheRequestAsync(key, request); var ssoContext = new InitiateSsoContext { PartnerId = partner.Id, Partner = partner, ReturnUrl = GenerateReturnUrl(context, key) }; await Events.InvokeAsync(Options, partner, e => e.OnInitiateSso(context.RequestServices, ssoContext)); if (ssoContext.AuthenticationScheme != null) { await ChallengeAsync(context, request, ssoContext.ReturnUrl, ssoContext.AuthenticationPropertyItems, ssoContext.AuthenticationScheme); } else { await ChallengeAsync(context, request, ssoContext.ReturnUrl, ssoContext.AuthenticationPropertyItems); } }
protected void btnIdPLogin_Click(object sender, EventArgs e) { // Get the authentication request. Issuer issuer = new Issuer(Global.entityId); AuthnRequest authnRequest = Util.GetAuthnRequest(this); authnRequest.Issuer.NameIdentifier = Global.entityId; // Get SP Resource URL. string spResourceUrl = Util.GetAbsoluteUrl(this, FormsAuthentication.GetRedirectUrl("", false)); // Create relay state. string relayState = Guid.NewGuid().ToString(); // Save the SP Resource URL to the cache. SamlSettings.CacheProvider.Insert(relayState, spResourceUrl, new TimeSpan(1, 0, 0)); switch (Global.SingleSignOnServiceBinding) { case SamlBinding.HttpRedirect: X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.SpCertKey]; // Send authentication request using HTTP Redirect. System.Diagnostics.Debug.WriteLine("Sending redirect request to " + Global.SingleSignOnServiceURL); authnRequest.Redirect(Response, Global.SingleSignOnServiceURL, relayState, x509Certificate.PrivateKey, SignatureAlgorithms.RsaSha256); break; case SamlBinding.HttpPost: // Send authentication request using HTTP POST form. System.Diagnostics.Debug.WriteLine("Sending POST request to " + Global.SingleSignOnServiceURL); authnRequest.SendHttpPost(Response, Global.SingleSignOnServiceURL, relayState); // End the response. Response.End(); break; case SamlBinding.HttpArtifact: // Create a new http artifact. string identificationUrl = Util.GetAbsoluteUrl(this, "~/"); Saml2ArtifactType0004 httpArtifact = new Saml2ArtifactType0004(SamlArtifact.GetSourceId(identificationUrl), SamlArtifact.GetHandle()); // Save the authentication request for subsequent sending using the artifact resolution protocol. SamlSettings.CacheProvider.Insert(httpArtifact.ToString(), authnRequest.GetXml(), new TimeSpan(1, 0, 0)); // Send the artifact using HTTP POST form. httpArtifact.SendHttpPost(Response.OutputStream, Global.SingleSignOnServiceURL, relayState); // End the response. Response.End(); break; default: throw new ApplicationException("Invalid binding type"); } }
/// <summary> /// This Post Action is used to Generate the AuthN Request and redirect to the B2C Login endpoint /// </summary> public IActionResult OnPost(string Tenant, string Policy) { string b2cloginurl = _configuration["SAMLTEST:b2cloginurl"]; Policy = Policy.StartsWith("B2C_1A_") ? Policy : "B2C_1A_" + Policy; AuthnRequest AuthnReq = new AuthnRequest("https://" + b2cloginurl + "/te/" + Tenant + ".onmicrosoft.com/" + Policy + "/samlp/sso/login", SAMLHelper.GetThisURL(this)); string cdoc = SAMLHelper.Compress(AuthnReq.ToString()); string URL = "https://" + b2cloginurl + "/te/" + Tenant + ".onmicrosoft.com/" + Policy + "/samlp/sso/login?SAMLRequest=" + System.Web.HttpUtility.UrlEncode(cdoc); return(Redirect(URL)); }
protected void Page_Load(object sender, EventArgs e) { try { // Get the saved SSO state, if any. // If there isn't saved state then receive the authentication request. // If there is saved state then we've just completed a local login in response to a prior authentication request. SSOState ssoState = (SSOState)Session[ssoSessionKey]; if (ssoState == null) { Trace.Write("IdP", "SSO service"); // Receive the authentication request and relay state. AuthnRequest authnRequest = null; string relayState = null; ReceiveAuthnRequest(out authnRequest, out relayState); // Process the request. bool forceAuthn = authnRequest.ForceAuthn; ssoState = new SSOState(); ssoState.AuthnRequest = authnRequest; ssoState.RelayState = relayState; // Determine whether or not a local login is required. bool requireLocalLogin = IsLocalLoginRequired(forceAuthn); // If a local login is required then save the session state and initiate a local login. if (requireLocalLogin) { Session[ssoSessionKey] = ssoState; FormsAuthentication.RedirectToLoginPage(); return; } } // Create a SAML response with the user's local identity, if any. SAMLResponse samlResponse = CreateSAMLResponse(ssoState.AuthnRequest); // Send the SAML response to the service provider. SendSAMLResponse(samlResponse, ssoState.RelayState); // Clear the SSO state. Session[ssoSessionKey] = null; } catch (Exception exception) { Trace.Write("IdP", "Error in SSO service", exception); } }
public IActionResult SendAzureAdRequest(string Tenant) { AuthnRequest AuthnReq; AuthnReq = new AuthnRequest("https://login.microsoftonline.com/42cf448f-0704-4dd0-85b5-87e61c2804a9/saml2", SAMLHelper.GetThisURL(this), string.Empty); string cdoc = SAMLHelper.Compress(AuthnReq.ToString()); string URL = $"https://login.microsoftonline.com/42cf448f-0704-4dd0-85b5-87e61c2804a9/saml2?SAMLRequest=" + System.Web.HttpUtility.UrlEncode(cdoc); return(Redirect(URL)); }
public void AuthnRequestObjectTest() { string xmlString = ReadFile(xmlFilename); Saml2Serializer saml = new Saml2Serializer(); AuthnRequest authnRequest = saml.ConvertXMLToAuthnRequestObject(xmlString); Assert.AreEqual("https://stiamhub:8443/Hub/SAML/SSO/Browser", authnRequest.Destination); Assert.AreEqual("http://localhost:14545/", authnRequest.AssertionConsumerServiceURL); Assert.AreEqual("hybridissuer.ch", authnRequest.Issuer); //Assert.AreEqual("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", authnRequest.NameIDPolicy.Format); }
// Create a SAML response with the user's local identity, if any, or indicating an error. private SAMLResponse CreateSAMLResponse(AuthnRequest authnRequest) { Trace.Write("IdP", "Creating SAML response"); SAMLResponse samlResponse = new SAMLResponse(); samlResponse.InResponseTo = authnRequest.ID; samlResponse.Destination = authnRequest.AssertionConsumerServiceURL; Issuer issuer = new Issuer(CreateAbsoluteURL("~/")); samlResponse.Issuer = issuer; if (User.Identity.IsAuthenticated) { samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Success, null); SAMLAssertion samlAssertion = new SAMLAssertion(); samlAssertion.Issuer = issuer; samlAssertion.Conditions = new Conditions(new TimeSpan(0, 10, 0)); AudienceRestriction audienceRestriction = new AudienceRestriction(); audienceRestriction.Audiences.Add(new Audience(authnRequest.AssertionConsumerServiceURL)); samlAssertion.Conditions.ConditionsList.Add(audienceRestriction); Subject subject = new Subject(new NameID(User.Identity.Name)); SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer); SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.InResponseTo = authnRequest.ID; subjectConfirmationData.Recipient = authnRequest.AssertionConsumerServiceURL; subjectConfirmationData.NotBefore = samlAssertion.Conditions.NotBefore; subjectConfirmationData.NotOnOrAfter = samlAssertion.Conditions.NotOnOrAfter; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; subject.SubjectConfirmations.Add(subjectConfirmation); samlAssertion.Subject = subject; AuthnStatement authnStatement = new AuthnStatement(); authnStatement.AuthnContext = new AuthnContext(); authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Password); samlAssertion.Statements.Add(authnStatement); samlResponse.Assertions.Add(samlAssertion); } else { samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Responder, SAMLIdentifiers.SecondaryStatusCodes.AuthnFailed, "The user is not authenticated at the identity provider"); } Trace.Write("IdP", "Created SAML response"); return(samlResponse); }
public void SendAuthnRequest(string idpLocation, Saml2SsoBinding idpBinding, string fromSpEntityId, string returnUrl, HttpContextBase httpContext) { // Create the authentication request. var authnRequest = new AuthnRequest { Destination = idpLocation, Issuer = new Issuer(fromSpEntityId), ForceAuthn = false, NameIDPolicy = new NameIDPolicy(null, null, true), }; // Serialize the authentication request to XML for transmission. var authnRequestXml = authnRequest.ToXml(); // Don't sign if using HTTP redirect as the generated query string is too long for most browsers. if (idpBinding != Saml2SsoBinding.HttpRedirect) { // Sign the authentication request. var signingCertificate = _certificates.GetSigningCertificate(); SAMLMessageSignature.Generate(authnRequestXml, signingCertificate.PrivateKey, signingCertificate); } // Create and cache the relay state so we remember which SP resource the user wishes to access after SSO. SAML.HttpContext = httpContext; string relayState = null; if (!string.IsNullOrWhiteSpace(returnUrl)) { relayState = RelayStateCache.Add(new RelayState(returnUrl, null)); } // Send the authentication request to the identity provider over the configured binding. switch (idpBinding) { case Saml2SsoBinding.HttpPost: ServiceProvider.SendAuthnRequestByHTTPPost(httpContext.Response, idpLocation, authnRequestXml, relayState); httpContext.Response.End(); break; case Saml2SsoBinding.HttpRedirect: var encryptionCertificate = _certificates.GetEncryptionCertificate(); ServiceProvider.SendAuthnRequestByHTTPRedirect(httpContext.Response, idpLocation, authnRequestXml, relayState, encryptionCertificate.PrivateKey); break; default: throw new NotSupportedException(string.Format( "The '{0}' binding is currently not supported.", idpBinding.AsUriString())); } }
public void ValidateResponseWithoutTimeValidTest() { Saml2Serializer serializer = new Saml2Serializer(); SamlValidator validator = new SamlValidator(); string xml = Encoding.UTF8.GetString(Convert.FromBase64String(ReadFile(responseFilename))); EntityDescriptor entityDescriptor = serializer.ConvertXMLToEntityDescriptorObject(ReadFile(xmlMetadataFile)); AuthnRequest authnRequest = serializer.ConvertXMLToAuthnRequestObject(ReadFile(xmlAuthnRequestFile)); Response response = serializer.ConvertXMLToResponseObject(xml); bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); Assert.IsTrue(isValid); }
protected string SerializeAuthnRequest(AuthnRequest request, BindingType binding) { using (var memory = new MemoryStream()) { using (var writer = XmlWriter.Create(memory, new XmlWriterSettings { OmitXmlDeclaration = true, Indent = false, CloseOutput = false, Encoding = new UTF8Encoding(false) })) { Serializer.SerializeAuthnRequest(writer, request); } memory.Position = 0; return(Encoder.Encode(memory, binding)); } }
private Task StartSsoAsync(HttpContext context, AuthnRequest request, Uri destination, BindingType binding) { var base64 = SerializeAuthnRequest(request, binding); if (binding == BindingType.Post) { return(PostAsync(context, base64, destination, request.RelayState)); } if (binding == BindingType.Redirect) { return(RedirectAsync(context, base64, destination, request.RelayState)); } throw new ArgumentException($"Unsupported binding type: '{binding}'"); }
protected override void BuildInternal(AuthnRequest request, AuthnRequestConfiguration configuration) { if (configuration.RequestedAuthnContextConfiguration == null) { return; } var comparison = (AuthnContextComparisonType)Enum.Parse(typeof(AuthnContextComparisonType), configuration.RequestedAuthnContextConfiguration.Comparision); request.RequestedAuthnContext = new RequestedAuthnContext { Comparison = comparison, ItemsElementName = configuration.RequestedAuthnContextConfiguration.RequestedAuthnContexts.Select(x => (AuthnContextType)Enum.Parse(typeof(AuthnContextType), x.AuthnContextType)).ToArray(), Items = configuration.RequestedAuthnContextConfiguration.RequestedAuthnContexts.Select(x => x.AuthnContextUri.AbsoluteUri).ToArray() }; }
protected override void OnInit(EventArgs e) { request = Context.Session["authenticationrequest"] as AuthnRequest; if (request == null) { HandleRequestMissing(); return; } if (request.RequestedAuthnContext != null) { for (int i = 0; i < request.RequestedAuthnContext.ItemsElementName.Length; i++) { var elementName = request.RequestedAuthnContext.ItemsElementName[i]; if (elementName == ItemsChoiceType7.AuthnContextClassRef) { if (request.RequestedAuthnContext.Items.Length <= i) { Context.Response.Write(string.Format("The RequestedAuthnContext {0} could not be determined.", i)); Context.Response.End(); return; } SPDesiredContext.Text += request.RequestedAuthnContext.Items[i] + "<br/>"; } } if (!string.IsNullOrEmpty(SPDesiredContext.Text)) { DemandArea.Visible = true; } } User user = UserSessionsHandler.CurrentUser; if (user != null) { // don't issue new assertion if ForceAuthn is set if (request.ForceAuthn.HasValue && request.ForceAuthn.Value) { return; } // User has a previous session on the IDP. Issue a new assertion. CreateAssertionResponse(user); } }
/// <summary> /// Processes the authentication request. /// </summary> /// <param name="authnRequest">The AuthnRequest object.</param> /// <param name="relayState">The relayState string.</param> public static void ProcessAuthnRequest(Page page, out AuthnRequest authnRequest, out string relayState) { // Use a single endpoint and use a query string parameter to determine the Service Provider to Identity Provider binding type. string bindingType = page.Request.QueryString[SP2IdPBindingTypeVar]; // Get the previously loaded certificate. X509Certificate2 cert = (X509Certificate2)page.Application[Global.SPCertKey]; switch (bindingType) { case RedirectBinding: authnRequest = AuthnRequest.Create(page.Request.RawUrl, cert.PublicKey.Key); relayState = authnRequest.RelayState; break; case PostBinding: authnRequest = AuthnRequest.CreateFromHttpPost(page.Request); relayState = authnRequest.RelayState; break; case ArtifactBinding: Saml2ArtifactType0004 httpArtifact = Saml2ArtifactType0004.CreateFromHttpArtifactHttpForm(page.Request); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(new Uri(page.Request.Url, page.ResolveUrl("~/")).ToString()); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); // Send the SAML Artifact Resolve Request and parse the received response. ArtifactResponse artifactResponse = ArtifactResponse.SendSamlMessageReceiveAftifactResponse(Global.ArtifactResolutionUrl, artifactResolve); // Extract the authentication request from the received artifact response. authnRequest = new AuthnRequest(artifactResponse.Message); relayState = httpArtifact.RelayState; break; default: throw new ApplicationException("Invalid binding type"); } if (authnRequest.IsSigned()) { if (!authnRequest.Validate(cert)) { throw new ApplicationException("The authentication request signature failed to verify."); } } }
public void SendAuthnRequest(string idpLocation, Saml2SsoBinding idpBinding, string fromSpEntityId, string returnUrl, HttpContextBase httpContext) { // Create the authentication request. var authnRequest = new AuthnRequest { Destination = idpLocation, Issuer = new Issuer(fromSpEntityId), ForceAuthn = false, NameIDPolicy = new NameIDPolicy(null, null, true), }; // Serialize the authentication request to XML for transmission. var authnRequestXml = authnRequest.ToXml(); // Don't sign if using HTTP redirect as the generated query string is too long for most browsers. if (idpBinding != Saml2SsoBinding.HttpRedirect) { // Sign the authentication request. var signingCertificate = _certificates.GetSigningCertificate(); SAMLMessageSignature.Generate(authnRequestXml, signingCertificate.PrivateKey, signingCertificate); } // Create and cache the relay state so we remember which SP resource the user wishes to access after SSO. SAML.HttpContext = httpContext; string relayState = null; if (!string.IsNullOrWhiteSpace(returnUrl)) relayState = RelayStateCache.Add(new RelayState(returnUrl, null)); // Send the authentication request to the identity provider over the configured binding. switch (idpBinding) { case Saml2SsoBinding.HttpPost: ServiceProvider.SendAuthnRequestByHTTPPost(httpContext.Response, idpLocation, authnRequestXml, relayState); httpContext.Response.End(); break; case Saml2SsoBinding.HttpRedirect: var encryptionCertificate = _certificates.GetEncryptionCertificate(); ServiceProvider.SendAuthnRequestByHTTPRedirect(httpContext.Response, idpLocation, authnRequestXml, relayState, encryptionCertificate.PrivateKey); break; default: throw new NotSupportedException(string.Format( "The '{0}' binding is currently not supported.", idpBinding.AsUriString())); } }
protected override void BuildInternal(AuthnRequest request, AuthnRequestConfiguration configuration) { if (configuration.ScopingConfiguration == null) { return; } if (configuration.ScopingConfiguration.RequesterIds != null && configuration.ScopingConfiguration.RequesterIds.Count == 0) { configuration.ScopingConfiguration.RequesterIds.Add(configuration.EntityId); } request.Scoping = new Scoping { ProxyCount = configuration.ScopingConfiguration.PoxyCount.ToString(), RequesterId = configuration.ScopingConfiguration.RequesterIds.ToArray() }; }
/// <summary> /// Reads the given saml response and extracts the attributes /// </summary> /// <param name="samlResponse">saml response with or without encrypted assertion</param> /// <param name="relaystate">related state to saml response</param> /// <param name="responseAssertionAttributes">contains the extracted attributes from the assertion (if there were any)</param> /// <returns>true -> valid response -> else exception is thrown</returns> public bool ReadResponse(string samlResponse, string relaystate, out Dictionary <string, ResponseAssertionAttribute> responseAssertionAttributes) { if (!initialized) { throw new SamlCommunicationException("Init must be called first", SamlCommunicationType.SAMLCOMMUNICATION); } LogService.Log(LogService.LogType.Info, "ReadResponse called"); responseAssertionAttributes = new Dictionary <string, ResponseAssertionAttribute>(); try { LogService.Log(LogService.LogType.Info, "ReadResponse response: '" + samlResponse + "'; relatedstate: '" + relaystate + "'"); // decode SAMLResponse first (base64) string responseXML = Encoding.UTF8.GetString(Convert.FromBase64String(samlResponse)); // get response as object Response response = serializer.ConvertXMLToResponseObject(responseXML); // remove encrypted assertion if there is one if (response.EncryptedAssertion != null) { RemoveEncryptedAssertion(response); // TODO should check first if response is valid or not (saving computation power) } // load metadata from issuer EntityDescriptor metadata = LoadMetadataFile(response.Issuer, metadataDirectoryPath); // load AuthnRequest from archiver string authnRequestString = archiver.GetArchivedObject(response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.InResponseTo); AuthnRequest authnRequest = serializer.ConvertXMLToAuthnRequestObject(Encoding.UTF8.GetString(Convert.FromBase64String(authnRequestString))); // check if response is valid if (verifier.ValidateResponse(response, responseXML, metadata, authnRequest)) { LogService.Log(LogService.LogType.Info, "ReadResponse extract attributes from response"); responseAssertionAttributes = serializer.GetAttributes(response); return(true); } throw new SamlCommunicationException("Response is not valid."); } catch (Exception e) { LogService.Log(LogService.LogType.FatalError, "ReadResponse failed", e); throw new SamlCommunicationException("ReadResponse failed", e, SamlCommunicationType.SAMLCOMMUNICATION); } }
static void Main(string[] args) { try { #if DOTNET45 // Register the SHA-256 cryptographic algorithm. // Only supported in .NET 4.5 and above. CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); #endif // Load the certificate and private key for signature generation. X509Certificate2 x509Certificate = new X509Certificate2("idp.pfx", "password"); // Create a basic SAML assertion and serialize it to XML. SAMLAssertion samlAssertion = new SAMLAssertion(); samlAssertion.Issuer = new Issuer("test"); XmlElement samlAssertionElement = samlAssertion.ToXml(); // Sign the SAML assertion using SHA-256 for the digest and signature algorithms. SAMLAssertionSignature.Generate(samlAssertionElement, x509Certificate.PrivateKey, x509Certificate, null, "http://www.w3.org/2001/04/xmlenc#sha256", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); Console.WriteLine("Signed SAML assertion: {0}", samlAssertionElement.OuterXml); // Verify the signature. bool verified = SAMLAssertionSignature.Verify(samlAssertionElement); Console.WriteLine("Signature verified: {0}", verified); // The HTTP-redirect doesn't use XML signatures so check it separately. // Create a basic authn request and serialize it to XML. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Issuer = new Issuer("test"); XmlElement authnRequestElement = authnRequest.ToXml(); // Create the HTTP-redirect URL included the SHA-256 signature. string url = HTTPRedirectBinding.CreateRequestRedirectURL("http://www.test.com", authnRequestElement, null, x509Certificate.PrivateKey, HTTPRedirectBinding.SignatureAlgorithms.RSA_SHA256); string relayState = null; bool signed = false; // Retrieve the authn request from the HTTP-redirect URL and verify the signature. HTTPRedirectBinding.GetRequestFromRedirectURL(url, out authnRequestElement, out relayState, out signed, x509Certificate.PublicKey.Key); } catch (Exception exception) { // If signature generation/verification fails then most likely the .NET CLR security update // hasn't been installed and configured correctly or the inbuilt .NET SHA-256 support hasn't been initialized. Console.WriteLine(exception.ToString()); } }
private static void SignAndVerify(X509Certificate2 x509Certificate, string digestMethod, string signatureMethod) { try { Console.WriteLine("Testing signature generation and verification using \"{0}\".", signatureMethod); // Create a basic SAML assertion and serialize it to XML. SAMLAssertion samlAssertion = new SAMLAssertion(); samlAssertion.Issuer = new Issuer("test"); XmlElement samlAssertionElement = samlAssertion.ToXml(); // Sign the SAML assertion using the specified digest and signature methods. SAMLAssertionSignature.Generate(samlAssertionElement, x509Certificate.PrivateKey, x509Certificate, null, digestMethod, signatureMethod); // Verify the signature. bool verified = SAMLAssertionSignature.Verify(samlAssertionElement); if (!verified) { throw new Exception("The XML signature failed to verify."); } // The HTTP-redirect doesn't use XML signatures so check it separately. // Create a basic authn request and serialize it to XML. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Issuer = new Issuer("test"); XmlElement authnRequestElement = authnRequest.ToXml(); // Create the HTTP-redirect URL included the signature. string url = HTTPRedirectBinding.CreateRequestRedirectURL("http://www.test.com", authnRequestElement, null, x509Certificate.PrivateKey, signatureMethod); string relayState = null; bool signed = false; // Retrieve the authn request from the HTTP-redirect URL and verify the signature. HTTPRedirectBinding.GetRequestFromRedirectURL(url, out authnRequestElement, out relayState, out signed, x509Certificate.PublicKey.Key); Console.WriteLine("Signature generation and verification using \"{0}\" was successful.", signatureMethod); } catch (Exception exception) { Console.WriteLine("Signature generation and verification using \"{0}\" failed.", signatureMethod); Console.WriteLine(exception.ToString()); } }
/// <summary> /// Verify the request and transfer the login-page. /// </summary> /// <param name="parser"></param> private static void Signin(HttpRedirectBindingParser parser) { AuthnRequest req = Serialization.DeserializeFromXmlString <AuthnRequest>(parser.Message); // Retrieve metadata of requestor. string SPID = req.Issuer.Value; Saml20MetadataDocument SPmetadata = GetMetadata(SPID); if (parser.IsSigned && !CheckRedirectSignature(parser, SPmetadata)) { HandleUnableToVerifySignature(SPID); return; } HttpContext.Current.Session["authenticationrequest"] = req; HttpContext.Current.Server.Transfer("SignonForm.aspx"); }
private XmlElement CreateAuthnRequest() { // Create the authentication request. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Destination = "https://login.microsoftonline.com/021af3dc-d776-4348-8539-7eab9f6ce3fb/saml2";// Configuration.SingleSignOnServiceURL; authnRequest.Issuer = new Issuer("http://localhost/WebDrawer"); authnRequest.ForceAuthn = false; authnRequest.NameIDPolicy = new NameIDPolicy(null, null, true); // Serialize the authentication request to XML for transmission. XmlElement authnRequestXml = authnRequest.ToXml(); return(authnRequestXml); }
protected void Page_Load(object sender, EventArgs e) { RecieveSAMLSSORequest ssoreq = new RecieveSAMLSSORequest(); AuthnRequest authrequest = ssoreq.RecieveSSO(Request); if (!User.Identity.IsAuthenticated) { FormsAuthentication.RedirectToLoginPage(); return; } SendSAMLSSOResponse ssoresp = new SendSAMLSSOResponse(); Dictionary <string, string> attributes = new Dictionary <string, string>(); attributes.Add("Attribute1", "Preferred"); attributes.Add("Attribute2", "India"); ssoresp.SendSSO(Response, User.Identity.Name, attributes, authrequest); }
public void ShouldWriteAuthnRequestProtocolBindingAttribute(string expected) { var request = new AuthnRequest { ProtocolBinding = expected }; var serialized = _serializer.SerializeAuthnRequest(request); Assert.NotNull(serialized); var doc = XDocument.Parse(serialized); var root = doc.Root; var attribute = root.Attribute("ProtocolBinding"); Assert.NotNull(attribute?.Value); Assert.Equal(expected, attribute.Value); }
public void ShouldWriteAuthnRequestElementWithDefaultVersion() { var request = new AuthnRequest(); var serialized = _serializer.SerializeAuthnRequest(request); Assert.NotNull(serialized); var doc = XDocument.Parse(serialized); var root = doc.Root; var version = root.Attribute("Version"); Assert.Equal("samlp", doc.Root.GetPrefixOfNamespace(root.Name.Namespace)); Assert.Equal("AuthnRequest", root.Name.LocalName); Assert.Equal(_protocolNamespace, root.Name.Namespace); Assert.NotNull(version?.Value); Assert.Equal("2.0", version.Value); }
/// <summary> /// Gets the authentication request. /// </summary> /// <param name="page">The page object.</param> /// <returns>The authentication request object.</returns> public static AuthnRequest GetAuthnRequest(Page page) { // Create the authentication request. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Destination = Global.SingleSignOnServiceURL; authnRequest.Issuer = new Issuer(GetAbsoluteUrl(page, "~/")); authnRequest.ForceAuthn = false; authnRequest.NameIdPolicy = new NameIdPolicy(null, null, true); if (Global.SingleSignOnServiceBinding != SamlBinding.HttpRedirect) { // Sign the authentication request if the SSO service binding is not HTTP Redirect. // Get the certificate. X509Certificate2 x509Certificate = (X509Certificate2)page.Application[Global.SpCertKey]; // Sign the SAML request. authnRequest.Sign(x509Certificate); } return authnRequest; }
// Create an authentication request. private XmlElement CreateAuthnRequest() { // Create the authentication request. AuthnRequest authnRequest = new AuthnRequest(); authnRequest.Destination = Configuration.SingleSignOnServiceURL; authnRequest.Issuer = new Issuer(Configuration.Issuer); authnRequest.ForceAuthn = false; authnRequest.NameIDPolicy = new NameIDPolicy(null, null, true); // Serialize the authentication request to XML for transmission. XmlElement authnRequestXml = authnRequest.ToXml(); // Don't sign if using HTTP redirect as the generated query string is too long for most browsers. if (Configuration.SingleSignOnServiceBinding != SAMLIdentifiers.Binding.HTTPRedirect) { // Sign the authentication request. X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.SPX509Certificate]; SAMLMessageSignature.Generate(authnRequestXml, x509Certificate.PrivateKey, x509Certificate); } return authnRequestXml; }
// Receive the authentication request and relay state. private void ReceiveAuthnRequest(out AuthnRequest authnRequest, out string relayState) { Trace.Write("IdP", "Receiving authentication request over binding"); XmlElement authnRequestXml = null; bool signed = false; IdentityProvider.ReceiveAuthnRequestByHTTPRedirect(Request, out authnRequestXml, out relayState, out signed, null); if (SAMLMessageSignature.IsSigned(authnRequestXml)) { Trace.Write("IdP", "Verifying request signature"); if (!SAMLMessageSignature.Verify(authnRequestXml)) { throw new ArgumentException("The authentication request signature failed to verify."); } } authnRequest = new AuthnRequest(authnRequestXml); Trace.Write("IdP", "Received authentication request"); }
// Receive the authentication request and relay state. private void ReceiveAuthnRequest(out AuthnRequest authnRequest, out string relayState) { // Rather than separate endpoints per binding, we have a single endpoint and use a query string // parameter to determine the service provider to identity provider binding type. string bindingType = Request.QueryString[bindingQueryParameter]; Trace.Write("IdP", "Receiving authentication request over binding " + bindingType); X509Certificate2 x509Certificate = (X509Certificate2)Application[Global.SPX509Certificate]; XmlElement authnRequestXml = null; switch (bindingType) { case BindingTypes.Redirect: bool signed = false; IdentityProvider.ReceiveAuthnRequestByHTTPRedirect(Request, out authnRequestXml, out relayState, out signed, x509Certificate.PublicKey.Key); break; case BindingTypes.Post: IdentityProvider.ReceiveAuthnRequestByHTTPPost(Request, out authnRequestXml, out relayState); break; case BindingTypes.Artifact: // Receive the artifact. HTTPArtifact httpArtifact = null; IdentityProvider.ReceiveArtifactByHTTPArtifact(Request, false, out httpArtifact, out relayState); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(CreateAbsoluteURL("~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); XmlElement artifactResolveXml = artifactResolve.ToXml(); // Send the artifact resolve request and receive the artifact response. XmlElement artifactResponseXml = ArtifactResolver.SendRequestReceiveResponse(Configuration.ArtifactResolutionServiceURL, artifactResolveXml); ArtifactResponse artifactResponse = new ArtifactResponse(artifactResponseXml); // Extract the authentication request from the artifact response. authnRequestXml = artifactResponse.SAMLMessage; break; default: throw new ArgumentException("Invalid binding type"); } if (SAMLMessageSignature.IsSigned(authnRequestXml)) { Trace.Write("IdP", "Verifying request signature"); if (!SAMLMessageSignature.Verify(authnRequestXml, x509Certificate)) { throw new ArgumentException("The authentication request signature failed to verify."); } } authnRequest = new AuthnRequest(authnRequestXml); Trace.Write("IdP", "Received authentication request"); }
// Create a SAML response with the user's local identity, if any, or indicating an error. private SAMLResponse CreateSAMLResponse(AuthnRequest authnRequest) { Trace.Write("IdP", "Creating SAML response"); SAMLResponse samlResponse = new SAMLResponse(); samlResponse.Destination = Configuration.AssertionConsumerServiceURL; Issuer issuer = new Issuer(CreateAbsoluteURL("~/")); samlResponse.Issuer = issuer; if (User.Identity.IsAuthenticated) { samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Success, null); SAMLAssertion samlAssertion = new SAMLAssertion(); samlAssertion.Issuer = issuer; Subject subject = new Subject(new NameID(User.Identity.Name)); SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer); SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.InResponseTo = authnRequest.ID; subjectConfirmationData.Recipient = Configuration.AssertionConsumerServiceURL; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; subject.SubjectConfirmations.Add(subjectConfirmation); samlAssertion.Subject = subject; AuthnStatement authnStatement = new AuthnStatement(); authnStatement.AuthnContext = new AuthnContext(); authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Password); samlAssertion.Statements.Add(authnStatement); samlResponse.Assertions.Add(samlAssertion); } else { samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Responder, SAMLIdentifiers.SecondaryStatusCodes.AuthnFailed, "The user is not authenticated at the identity provider"); } Trace.Write("IdP", "Created SAML response"); return samlResponse; }
// Receive the authentication request from the service provider. private void ReceiveAuthnRequest(out AuthnRequest authnRequest, out string relayState) { // Determine the service provider to identity provider binding type. // We use a query string parameter rather than having separate endpoints per binding. string bindingType = Request.QueryString[bindingQueryParameter]; Trace.Write("IdP", "Receiving authentication request over binding " + bindingType); // Receive the authentication request. XmlElement authnRequestXml = null; switch (bindingType) { case SAMLIdentifiers.BindingURIs.HTTPRedirect: bool signed = false; X509Certificate2 x509Certificate = (X509Certificate2) Application[Global.SPX509Certificate]; IdentityProvider.ReceiveAuthnRequestByHTTPRedirect(Request, out authnRequestXml, out relayState, out signed, x509Certificate.PublicKey.Key); break; case SAMLIdentifiers.BindingURIs.HTTPPost: IdentityProvider.ReceiveAuthnRequestByHTTPPost(Request, out authnRequestXml, out relayState); break; case SAMLIdentifiers.BindingURIs.HTTPArtifact: // Receive the artifact. HTTPArtifact httpArtifact = null; IdentityProvider.ReceiveArtifactByHTTPArtifact(Request, false, out httpArtifact, out relayState); // Create an artifact resolve request. ArtifactResolve artifactResolve = new ArtifactResolve(); artifactResolve.Issuer = new Issuer(CreateAbsoluteURL("~/")); artifactResolve.Artifact = new Artifact(httpArtifact.ToString()); XmlElement artifactResolveXml = artifactResolve.ToXml(); // Send the artifact resolve request and receive the artifact response. string spArtifactResponderURL = WebConfigurationManager.AppSettings["spArtifactResponderURL"]; XmlElement artifactResponseXml = ArtifactResolver.SendRequestReceiveResponse(spArtifactResponderURL, artifactResolveXml); ArtifactResponse artifactResponse = new ArtifactResponse(artifactResponseXml); // Extract the authentication request from the artifact response. authnRequestXml = artifactResponse.SAMLMessage; break; default: throw new ArgumentException("Invalid service provider to identity provider binding"); } // If using HTTP redirect the message isn't signed as the generated query string is too long for most browsers. if (bindingType != SAMLIdentifiers.BindingURIs.HTTPRedirect) { if (SAMLMessageSignature.IsSigned(authnRequestXml)) { // Verify the request's signature. X509Certificate2 x509Certificate = (X509Certificate2) Application[Global.SPX509Certificate]; if (!SAMLMessageSignature.Verify(authnRequestXml, x509Certificate)) { throw new ArgumentException("The authentication request signature failed to verify."); } } } // Deserialize the XML. authnRequest = new AuthnRequest(authnRequestXml); Trace.Write("IdP", "Received authentication request"); }
public ActionResult Post(string returnUrl) { ViewBag.IdpUrl = ConfigurationManager.AppSettings["Saml2.IdpUrl"]; AuthnRequest request = new AuthnRequest(); var xmlString = request.XmlDoc.OuterXml; var bytes = Encoding.UTF8.GetBytes(xmlString); ViewBag.SamlRequest = Convert.ToBase64String(bytes); ViewBag.RelayState = Guid.NewGuid().ToString(); Session[ViewBag.RelayState] = returnUrl; return View(); }