Пример #1
0
        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
            });
        }
Пример #2
0
        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
            });
        }
Пример #3
0
        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);
        }
Пример #5
0
        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);
     }
 }
Пример #7
0
        /// <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());
        }
Пример #8
0
        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
            });
        }
Пример #9
0
        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
            }));
        }
Пример #10
0
        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
            });
        }