private static CommandResult ProcessResponse( IOptions options, Saml2Response samlResponse, StoredRequestState storedRequestState) { var principal = new ClaimsPrincipal(samlResponse.GetClaims(options)); principal = options.SPOptions.SystemIdentityModelIdentityConfiguration .ClaimsAuthenticationManager.Authenticate(null, principal); if (options.SPOptions.ReturnUrl == null) { if (storedRequestState == null) { throw new ConfigurationErrorsException(UnsolicitedMissingReturnUrlMessage); } if (storedRequestState.ReturnUrl == null) { throw new ConfigurationErrorsException(SpInitiatedMissingReturnUrl); } } return(new CommandResult() { HttpStatusCode = HttpStatusCode.SeeOther, Location = storedRequestState == null?null:storedRequestState.ReturnUrl ?? options.SPOptions.ReturnUrl, Principal = principal, RelayData = storedRequestState == null?null:storedRequestState.RelayData }); }
private static CommandResult ProcessResponse( IOptions options, Saml2Response samlResponse, StoredRequestState storedRequestState) { var principal = new ClaimsPrincipal(samlResponse.GetClaims(options, storedRequestState?.RelayData)); if (options.SPOptions.ReturnUrl == null) { if (storedRequestState == null) { throw new ConfigurationErrorsException(UnsolicitedMissingReturnUrlMessage); } if (storedRequestState.ReturnUrl == null) { throw new ConfigurationErrorsException(SpInitiatedMissingReturnUrl); } } options.SPOptions.Logger.WriteInformation("Successfully processed SAML response " + samlResponse.Id + " and authenticated " + principal.FindFirst(ClaimTypes.NameIdentifier)?.Value); return(new CommandResult() { HttpStatusCode = HttpStatusCode.SeeOther, Location = storedRequestState?.ReturnUrl ?? options.SPOptions.ReturnUrl, Principal = principal, RelayData = storedRequestState?.RelayData, SessionNotOnOrAfter = samlResponse.SessionNotOnOrAfter }); }
public static Saml2AuthResponse Create(string samlResponse, Saml2Id responseToId, EntityId issuer, X509Certificate2 idpCert, X509Certificate2 serviceCertificate, EntityId serviceId) { var decoded = DecodeBase64(samlResponse); var xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(decoded); var response = new Saml2Response(xmlDoc.DocumentElement, responseToId); if (response.Status != Saml2StatusCode.Success) { log.LogWarning("SAML authentication error: " + response.Status + " (" + response.StatusMessage + ")"); return(new Saml2AuthResponse(false) { Status = response.Status }); } var spOptions = new SPOptions(); spOptions.EntityId = serviceId; spOptions.ServiceCertificates.Add(serviceCertificate); var options = new Options(spOptions); var idp = new IdentityProvider(issuer, spOptions); idp.SigningKeys.AddConfiguredKey(idpCert); options.IdentityProviders.Add(idp); var identities = response.GetClaims(options)?.ToArray(); if (identities == null || identities.Length == 0) { return(new Saml2AuthResponse(false)); } var identity = identities.First(); var firstName = identity.FindFirstValue(AttributeNames.GivenName); var lastName = identity.FindFirstValue(AttributeNames.Sn); var ssn = identity.FindFirstValue(AttributeNames.NationalIdentificationNumber); var nameId = identity.FindFirstValue(AttributeNames.NameIdentifier); var sessionId = identity.FindFirstValue(AttributeNames.SessionIndex); return(new Saml2AuthResponse(true) { FirstName = firstName, LastName = lastName, SSN = ssn, RelayState = response.RelayState, NameIdentifier = nameId, SessionIndex = sessionId }); }
public void Saml2Response_Ctor_FromData() { var issuer = "http://idp.example.com"; var identity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.NameIdentifier, "JohnDoe") }); var response = new Saml2Response(issuer, null, null, identity); response.Issuer.Should().Be(issuer); response.GetClaims().Single().ShouldBeEquivalentTo(identity); }
public static IEnumerable <ClaimsIdentity> GetClaimsIdentities(Saml2Response token) { try { return(token.GetClaims(samlOptions)); } catch (Saml2ResponseFailedValidationException exception) { Debug.WriteLine(exception.Message); throw new HttpException(401, exception.Message); } }
/// <summary> /// Verifies the response and gets authentication claim from the response. /// </summary> /// <param name="samlResponse">The SAML response.</param> /// <returns>The authentication claim.</returns> public static Claim[] VerifyResponseAndGetAuthenticationClaim(Saml2Response samlResponse) { // The response is verified when the claims are retrieved. var responseClaims = samlResponse.GetClaims(Kentor.AuthServices.Configuration.Options.FromConfiguration).ToList(); var claims = new List <Claim>(); foreach (var claimsIdentity in responseClaims) { var authClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type.Equals("http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod")); if (authClaim != null) { claims.Add(authClaim); break; } } return(claims.ToArray()); }
private static CommandResult ProcessResponse(IOptions options, Saml2Response samlResponse) { var principal = new ClaimsPrincipal(samlResponse.GetClaims(options)); principal = options.SPOptions.SystemIdentityModelIdentityConfiguration .ClaimsAuthenticationManager.Authenticate(null, principal); var requestState = samlResponse.GetRequestState(options); return(new CommandResult() { HttpStatusCode = HttpStatusCode.SeeOther, Location = requestState != null && requestState.ReturnUrl != null ? requestState.ReturnUrl : options.SPOptions.ReturnUrl, Principal = principal, RelayData = requestState == null ? null : requestState.RelayData }); }
public void AcsCommandResultCreated(CommandResult result, Saml2Response response) { spOptions.Logger.WriteInformation("SAML2 {Saml2Response}:" + JsonConvert.SerializeObject(response, Formatting.Indented)); // Bereits in Anwendung auf Mandant BAR vorhanden if (!HasValidMandant(result)) { spOptions.Logger.WriteInformation("User hat noch keinen Antrag gestellt"); HttpContext.Current.Response.Redirect(GetLoginMandantErstellenUrl(), false); return; } var assertion = response.XmlElement.ChildNodes.OfType <XmlNode>() .First(node => node.Name == "saml2:Assertion"); var authnStatement = assertion.ChildNodes.OfType <XmlNode>() .First(node => node.Name == "saml2:AuthnStatement"); var authnContext = authnStatement.ChildNodes.OfType <XmlNode>() .First(node => node.Name == "saml2:AuthnContext"); var authnContextClassRef = authnContext.ChildNodes.OfType <XmlNode>() .First(node => node.Name == "saml2:AuthnContextClassRef"); var authType = authnContextClassRef.InnerText; var roles = result.Principal.Claims.Where( c => c.Type == "http://schemas.eiam.admin.ch/ws/2013/12/identity/claims/role" || c.Type == "http://schemas.eiam.admin.ch/ws/2013/12/identity/claims/e-id/profile/role"); // Prüfen ob eine Rolle Deny enthält oder leer ist (Rolle Deny?) var prefexRole = isPublicClient ? "BAR-recherche" : "BAR-recherche-management-client"; if (roles.Any( role => role.Value.EndsWith($"{prefexRole}.DENY", StringComparison.InvariantCultureIgnoreCase) || role.Value == string.Empty)) { spOptions.Logger.WriteError("User enthält DENY Rolle {Saml2Response}" + JsonConvert.SerializeObject(response, Formatting.Indented), null); result.HttpStatusCode = HttpStatusCode.Forbidden; return; } // Prüfen ob mind. eine Rolle Allow (Rolle Allow?) if (!roles.Any(role => role.Value.EndsWith($"{prefexRole}.ALLOW", StringComparison.InvariantCultureIgnoreCase))) { spOptions.Logger.WriteError( "User enthält keine ALLOW Rolle {Saml2Response}" + JsonConvert.SerializeObject(response, Formatting.Indented), null); result.HttpStatusCode = HttpStatusCode.Forbidden; return; } // Prüfen ob valide Anmeldeart (Bekannte Anmeldeart?) if (!IsValidLoginType(authType)) { spOptions.Logger.WriteError("User verwendet eine nicht zugelassen Anmeldeart {authType}" + authType, null); result.HttpStatusCode = HttpStatusCode.Forbidden; return; } spOptions.Logger.WriteVerbose("(AuthServiceNotifications:AcsCommandResultCreated()): {COMMANDRESULT}" + JsonConvert.SerializeObject(result, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore })); spOptions.Logger.WriteVerbose("(AuthServiceNotifications:AcsCommandResultCreated()): {Saml2Response}" + JsonConvert.SerializeObject(response, Formatting.Indented)); // Fehlende Claims hinzufügen (Custom-Roles kommen sonst nicht mit!) var options = Options.FromConfiguration; var identity = response.GetClaims(options).FirstOrDefault(); // Gemäss BIT-Doku gibt es nur eine Assertion in der SAML Response if (identity != null) { var claims = identity.Claims ?? Enumerable.Empty <Claim>(); foreach (var claim in claims) { if (!((ClaimsIdentity)result.Principal.Identity).HasClaim(claim.Type, claim.Value)) { spOptions.Logger.WriteVerbose("Adding Claim, because it is missing {CLAIM}: " + claim); ((ClaimsIdentity)result.Principal.Identity).AddClaim(claim); } else { spOptions.Logger.WriteVerbose("Not Adding Claim, because it already exists {CLAIM}: " + claim); } } } spOptions.Logger.WriteInformation("(AuthServiceNotifications:AcsCommandResultCreated()): {READCLAIMS}" + JsonConvert.SerializeObject(((ClaimsIdentity)result.Principal.Identity).Claims, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore })); }
public static Saml2AuthResponse Create(string samlResponse, Saml2Id responseToId, EntityId issuer, X509Certificate2 idpCert, X509Certificate2 serviceCertificate, EntityId serviceId) { var decoded = DecodeBase64(samlResponse); var xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(decoded); var response = new Saml2Response(xmlDoc.DocumentElement, responseToId); if (response.Status != Saml2StatusCode.Success) { log.LogWarning("SAML authentication error: " + response.Status + " (" + response.StatusMessage + ")"); return(new Saml2AuthResponse(false) { Status = response.Status }); } var spOptions = new SPOptions(); spOptions.EntityId = serviceId; spOptions.ServiceCertificates.Add(serviceCertificate); var options = new Options(spOptions); var idp = new IdentityProvider(issuer, spOptions); idp.SigningKeys.AddConfiguredKey(idpCert); options.IdentityProviders.Add(idp); System.Security.Claims.ClaimsIdentity[] identities = null; try { identities = response.GetClaims(options)?.ToArray(); } catch (Sustainsys.Saml2.Exceptions.Saml2ResponseFailedValidationException ex) { if (ex.Message.Contains("could not be decrypted") && decoded.Contains("http://www.w3.org/2009/xmlenc11#aes128-gcm")) { DecryptAesGcmHybrid(xmlDoc, serviceCertificate); return(ParseResponseFromXml(xmlDoc)); } else { throw; } } if (identities == null || identities.Length == 0) { return(new Saml2AuthResponse(false)); } var identity = identities.First(); var firstName = identity.FindFirstValue(AttributeNames.GivenName) ?? identity.FindFirstValue(AttributeNames.EidasCurrentGivenName); var lastName = identity.FindFirstValue(AttributeNames.Sn); var ssn = identity.FindFirstValue(AttributeNames.NationalIdentificationNumber); var foreignPersonIdentifier = identity.FindFirstValue(AttributeNames.ForeignPersonIdentifier); var nameId = identity.FindFirstValue(AttributeNames.NameIdentifier); var sessionId = identity.FindFirstValue(AttributeNames.SessionIndex); return(new Saml2AuthResponse(true) { FirstName = firstName, LastName = lastName, SSN = ssn, RelayState = response.RelayState, NameIdentifier = nameId, SessionIndex = sessionId, ForeignPersonIdentifier = foreignPersonIdentifier }); }