public async Task<SignInResponseMessage> GenerateResponseAsync(SignInValidationResult validationResult)
        {
            Logger.Info("Creating WS-Federation signin response");

            // create subject
            var outgoingSubject = await CreateSubjectAsync(validationResult);

            // create token for user
            var token = CreateSecurityToken(validationResult, outgoingSubject);

            // return response
            var rstr = new RequestSecurityTokenResponse
            {
                AppliesTo = new EndpointReference(validationResult.RelyingParty.Realm),
                Context = validationResult.SignInRequestMessage.Context,
                ReplyTo = validationResult.ReplyUrl,
                RequestedSecurityToken = new RequestedSecurityToken(token)
            };

            var serializer = new WSFederationSerializer(
                new WSTrust13RequestSerializer(),
                new WSTrust13ResponseSerializer());

            var mgr = SecurityTokenHandlerCollectionManager.CreateEmptySecurityTokenHandlerCollectionManager();
            mgr[SecurityTokenHandlerCollectionManager.Usage.Default] = CreateSupportedSecurityTokenHandler();
            
            var responseMessage = new SignInResponseMessage(
                new Uri(validationResult.ReplyUrl),
                rstr,
                serializer,
                new WSTrustSerializationContext(mgr));

            return responseMessage;
        }
 /// <summary>
 /// Custom validation logic for the sign in request.
 /// </summary>
 /// <param name="request">The validated request.</param>
 /// <returns>The validation result</returns>
 public Task<SignInValidationResult> ValidateSignInRequestAsync(SignInValidationResult request)
 {
     return Task.FromResult(new SignInValidationResult
     {
         IsError = false
     });
 }
        public async Task <SignInValidationResult> ValidateAsync(SignInRequestMessage message, ClaimsPrincipal subject)
        {
            Logger.Info("Start WS-Federation signin request validation");
            var result = new SignInValidationResult();

            // parse whr
            if (!String.IsNullOrWhiteSpace(message.HomeRealm))
            {
                result.HomeRealm = message.HomeRealm;
            }

            // parse wfed
            if (!String.IsNullOrWhiteSpace(message.Federation))
            {
                result.Federation = message.Federation;
            }

            // check realm
            var rp = await _relyingParties.GetByRealmAsync(message.Realm);

            if (rp == null || rp.Enabled == false)
            {
                LogError("Relying party not found: " + message.Realm, result);

                return(new SignInValidationResult
                {
                    IsError = true,
                    Error = "invalid_relying_party"
                });
            }

            if (!subject.Identity.IsAuthenticated)
            {
                result.IsSignInRequired = true;
                return(result);
            }

            result.ReplyUrl             = rp.ReplyUrl;
            result.RelyingParty         = rp;
            result.SignInRequestMessage = message;
            result.Subject = subject;

            Logger.Debug("Calling into custom validator: " + _customValidator.GetType().FullName);
            var customResult = await _customValidator.ValidateSignInRequestAsync(result);

            if (customResult.IsError)
            {
                LogError("Error in custom validation: " + customResult.Error, result);
                return(new SignInValidationResult
                {
                    IsError = true,
                    Error = customResult.Error,
                    ErrorMessage = customResult.ErrorMessage,
                });
            }

            LogSuccess(result);
            return(result);
        }
        public async Task<SignInValidationResult> ValidateAsync(SignInRequestMessage message, ClaimsPrincipal subject)
        {
            Logger.Info("Start WS-Federation signin request validation");
            var result = new SignInValidationResult();

            // parse whr
            if (!String.IsNullOrWhiteSpace(message.HomeRealm))
            {
                result.HomeRealm = message.HomeRealm;
            }

            // parse wfed
            if (!String.IsNullOrWhiteSpace(message.Federation))
            {
                result.Federation = message.Federation;
            }

            if (!subject.Identity.IsAuthenticated)
            {
                result.IsSignInRequired = true;
                return result;
            }

            // check realm
            var rp = await _relyingParties.GetByRealmAsync(message.Realm);

            if (rp == null || rp.Enabled == false)
            {
                LogError("Relying party not found: " + message.Realm, result);

                return new SignInValidationResult
                {
                    IsError = true,
                    Error = "invalid_relying_party"
                };
            }

            result.ReplyUrl = rp.ReplyUrl;
            result.RelyingParty = rp;
            result.SignInRequestMessage = message;
            result.Subject = subject;

            var customResult = await _customValidator.ValidateSignInRequestAsync(result);
            if (customResult.IsError)
            {
                LogError("Error in custom validation: " + customResult.Error, result);
                return new SignInValidationResult
                    {
                        IsError = true,
                        Error = customResult.Error,
                        ErrorMessage = customResult.ErrorMessage,
                    };
            }

            LogSuccess(result);
            return result;
        }
        public SignInValidationLog(SignInValidationResult result)
        {
            if (result.RelyingParty != null)
            {
                Realm = result.RelyingParty.Realm;
                RelyingPartyName = result.RelyingParty.Name;
            }

            if (Subject != null)
            {
                Subject = result.Subject.GetSubjectId();
            }

            ReplyUrl = result.ReplyUrl;
            HomeRealm = result.HomeRealm;
            Federation = result.Federation;
        }
Ejemplo n.º 6
0
        IHttpActionResult RedirectToLogin(SignInValidationResult result)
        {
            Uri publicRequestUri = GetPublicRequestUri();

            var message = new SignInMessage();
            message.ReturnUrl = publicRequestUri.ToString();

            if (!String.IsNullOrWhiteSpace(result.HomeRealm))
            {
                message.IdP = result.HomeRealm;
            }

            if (!String.IsNullOrWhiteSpace(result.Federation))
            {
                message.AcrValues = new[] { result.Federation };
            }
            
            var env = Request.GetOwinEnvironment();
            var url = env.CreateSignInRequest(message);
            
            return Redirect(url);
        }
        private async Task<ClaimsIdentity> CreateSubjectAsync(SignInValidationResult validationResult)
        {
            var profileClaims = new List<Claim>();
            var mappedClaims = new List<Claim>();

            // get all claims from user service
            if (validationResult.RelyingParty.IncludeAllClaimsForUser)
            {
                var ctx = new ProfileDataRequestContext
                {
                    Subject = validationResult.Subject,
                    AllClaimsRequested = true
                };
                await _users.GetProfileDataAsync(ctx);
                
                profileClaims = ctx.IssuedClaims.ToList();
            }
            else
            {
                // get only claims that are explicitly mapped (if any)
                var claimTypes = validationResult.RelyingParty.ClaimMappings.Keys;

                if (claimTypes.Any())
                {
                    var ctx = new ProfileDataRequestContext
                    {
                        Subject = validationResult.Subject,
                        RequestedClaimTypes = claimTypes
                    };
                    await _users.GetProfileDataAsync(ctx);

                    profileClaims = ctx.IssuedClaims.ToList();
                }
            }
            
            foreach (var claim in profileClaims)
            {
                string mappedType;

                // if an explicit mapping exists, use it
                if (validationResult.RelyingParty.ClaimMappings.TryGetValue(claim.Type, out mappedType))
                {
                    // if output claim is a SAML name ID - check is any name ID format is configured
                    if (mappedType == ClaimTypes.NameIdentifier)
                    {
                        var nameId = new Claim(ClaimTypes.NameIdentifier, claim.Value);
                        if (!string.IsNullOrEmpty(validationResult.RelyingParty.SamlNameIdentifierFormat))
                        {
                            nameId.Properties[ClaimProperties.SamlNameIdentifierFormat] = validationResult.RelyingParty.SamlNameIdentifierFormat;
                        }

                        mappedClaims.Add(nameId);
                    }
                    else
                    {
                        mappedClaims.Add(new Claim(mappedType, claim.Value));
                    }
                }
                else
                {
                    // otherwise pass-through the claims if flag is set
                    if (validationResult.RelyingParty.IncludeAllClaimsForUser)
                    {
                        string newType = claim.Type;

                        // if prefix is configured, prefix the claim type
                        if (!string.IsNullOrWhiteSpace(validationResult.RelyingParty.DefaultClaimTypeMappingPrefix))
                        {
                            newType = validationResult.RelyingParty.DefaultClaimTypeMappingPrefix + newType;
                        }

                        mappedClaims.Add(new Claim(newType, claim.Value));
                    }
                }
            }

            if (validationResult.Subject.GetAuthenticationMethod() == Constants.AuthenticationMethods.Password)
            {
                mappedClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password));
                mappedClaims.Add(AuthenticationInstantClaim.Now);
            }
            
            return new ClaimsIdentity(mappedClaims, "idsrv");
        }
        private SecurityToken CreateSecurityToken(SignInValidationResult validationResult, ClaimsIdentity outgoingSubject)
        {
            var descriptor = new SecurityTokenDescriptor
            {
                AppliesToAddress = validationResult.RelyingParty.Realm,
                Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(validationResult.RelyingParty.TokenLifeTime)),
                ReplyToAddress = validationResult.ReplyUrl,
                SigningCredentials = new X509SigningCredentials(_options.SigningCertificate, validationResult.RelyingParty.SignatureAlgorithm, validationResult.RelyingParty.DigestAlgorithm),
                Subject = outgoingSubject,
                TokenIssuerName = _options.IssuerUri,
                TokenType = validationResult.RelyingParty.TokenType
            };

            if (validationResult.RelyingParty.EncryptingCertificate != null)
            {
                descriptor.EncryptingCredentials = new EncryptedKeyEncryptingCredentials(validationResult.RelyingParty.EncryptingCertificate);
            }

            return CreateSupportedSecurityTokenHandler().CreateToken(descriptor);
        }
Ejemplo n.º 9
0
        private void LogError(string message, SignInValidationResult result)
        {
            var log = LogSerializer.Serialize(new SignInValidationLog(result));

            Logger.ErrorFormat("{0}\n{1}", message, log);
        }
Ejemplo n.º 10
0
        private void LogSuccess(SignInValidationResult result)
        {
            var log = LogSerializer.Serialize(new SignInValidationLog(result));

            Logger.InfoFormat("End WS-Federation signin request validation\n{0}", log);
        }
        private void LogError(string message, SignInValidationResult result)
        {
            var log = new SignInValidationLog(result);

            Logger.ErrorFormat("{0}\n{1}", message, log.ToString());
        }
        private void LogSuccess(SignInValidationResult result)
        {
            var log = new SignInValidationLog(result);

            Logger.InfoFormat("End WS-Federation signin request validation\n{0}", log.ToString());
        }
 /// <summary>
 /// Transforms claims before they are sent back to relying party in response to sign in.
 /// </summary>
 /// <param name="validationResult">The validated request.</param>
 /// <param name="mappedClaims">Suggested claims</param>
 /// <returns>Final claims to include in response</returns>
 public Task<IEnumerable<Claim>> TransformClaimsAsync(SignInValidationResult validationResult, IEnumerable<Claim> mappedClaims)
 {
     return Task.FromResult(mappedClaims);
 }
        private async Task<ClaimsIdentity> CreateSubjectAsync(SignInValidationResult validationResult)
        {
            var profileClaims = new List<Claim>();
            var mappedClaims = new List<Claim>();

            // get all claims from user service
            if (validationResult.RelyingParty.IncludeAllClaimsForUser)
            {
                var ctx = new ProfileDataRequestContext
                {
                    Subject = validationResult.Subject,
                    AllClaimsRequested = true
                };
                await _users.GetProfileDataAsync(ctx);
                
                profileClaims = ctx.IssuedClaims.ToList();
            }
            else
            {
                // get only claims that are explicitly mapped (if any)
                var claimTypes = validationResult.RelyingParty.ClaimMappings.Keys;

                if (claimTypes.Any())
                {
                    var ctx = new ProfileDataRequestContext
                    {
                        Subject = validationResult.Subject,
                        RequestedClaimTypes = claimTypes
                    };
                    await _users.GetProfileDataAsync(ctx);

                    profileClaims = ctx.IssuedClaims.ToList();
                }
            }
            
            foreach (var claim in profileClaims)
            {
                string mappedType;

                // if an explicit mapping exists, use it
                if (validationResult.RelyingParty.ClaimMappings.TryGetValue(claim.Type, out mappedType))
                {
                    // if output claim is a SAML name ID - check is any name ID format is configured
                    if (mappedType == ClaimTypes.NameIdentifier)
                    {
                        var nameId = new Claim(ClaimTypes.NameIdentifier, claim.Value);
                        if (!string.IsNullOrEmpty(validationResult.RelyingParty.SamlNameIdentifierFormat))
                        {
                            nameId.Properties[ClaimProperties.SamlNameIdentifierFormat] = validationResult.RelyingParty.SamlNameIdentifierFormat;
                        }

                        mappedClaims.Add(nameId);
                    }
                    else
                    {
                        mappedClaims.Add(new Claim(mappedType, claim.Value));
                    }
                }
                else
                {
                    // otherwise pass-through the claims if flag is set
                    if (validationResult.RelyingParty.IncludeAllClaimsForUser)
                    {
                        string newType = claim.Type;

                        // if prefix is configured, prefix the claim type
                        if (!string.IsNullOrWhiteSpace(validationResult.RelyingParty.DefaultClaimTypeMappingPrefix))
                        {
                            newType = validationResult.RelyingParty.DefaultClaimTypeMappingPrefix + newType;
                        }

                        mappedClaims.Add(new Claim(newType, claim.Value));
                    }
                }
            }

            // The AuthnStatement statement generated from the following 2
            // claims is manditory for some service providers (i.e. Shibboleth-Sp). 
            // The value of the AuthenticationMethod claim must be one of the constants in
            // System.IdentityModel.Tokens.AuthenticationMethods.
            // Password is the only one that can be directly matched, everything
            // else defaults to Unspecified.
            if (validationResult.Subject.GetAuthenticationMethod() == Constants.AuthenticationMethods.Password)
            {
                mappedClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password));
            } else {
                mappedClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Unspecified));
            }
            mappedClaims.Add(AuthenticationInstantClaim.Now);

            var finalClaims = await _customClaimsService.TransformClaimsAsync(validationResult, mappedClaims);

            return new ClaimsIdentity(finalClaims, "idsrv");
        }
 private void LogSuccess(SignInValidationResult result)
 {
     var log = LogSerializer.Serialize(new SignInValidationLog(result));
     Logger.InfoFormat("End WS-Federation signin request validation\n{0}", log);
 }
 private void LogError(string message, SignInValidationResult result)
 {
     var log = LogSerializer.Serialize(new SignInValidationLog(result));
     Logger.ErrorFormat("{0}\n{1}", message, log);
 }