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 responseMessage = new SignInResponseMessage(
                new Uri(validationResult.ReplyUrl),
                rstr,
                serializer,
                new WSTrustSerializationContext());

            return responseMessage;
        }
        private async Task<ClaimsIdentity> CreateSubjectAsync(SignInValidationResult validationResult)
        {
            var claims = await _users.GetProfileDataAsync(
                validationResult.Subject.GetSubjectId(), 
                validationResult.RelyingParty.ClaimMappings.Keys);

            var mappedClaims = new List<Claim>();

            foreach (var claim in claims)
            {
                string mappedType;
                if (validationResult.RelyingParty.ClaimMappings.TryGetValue(claim.Type, out mappedType))
                {
                    mappedClaims.Add(new Claim(mappedType, 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");
        }
        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;
        }
        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;

            LogSuccess(result);
            return result;
        }
Example #5
0
        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;

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

            if (message.HomeRealm.IsPresent())
            {
                Logger.Info("Setting home realm to: " + message.HomeRealm);
                result.HomeRealm = message.HomeRealm;
            }

            // todo: wfresh handling?
            if (!subject.Identity.IsAuthenticated)
            {
                result.IsSignInRequired = true;
                return(result);
            }
            ;

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

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

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

            Logger.InfoFormat("Relying party registration found: {0} / {1}", rp.Realm, rp.Name);

            result.ReplyUrl = rp.ReplyUrl;
            Logger.InfoFormat("Reply URL set to: " + result.ReplyUrl);

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

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

            if (message.HomeRealm.IsPresent())
            {
                Logger.Info("Setting home realm to: " + message.HomeRealm);
                result.HomeRealm = message.HomeRealm;
            }

            // todo: wfresh handling?
            if (!subject.Identity.IsAuthenticated)
            {
                result.IsSignInRequired = true;
                return result;
            };

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

            if (rp == null || rp.Enabled == false)
            {
                Logger.Error("Relying party not found: " + rp.Realm);

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

            Logger.InfoFormat("Relying party registration found: {0} / {1}", rp.Realm, rp.Name);

            result.ReplyUrl = rp.ReplyUrl;
            Logger.InfoFormat("Reply URL set to: " + result.ReplyUrl);

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

            return result;
        }
        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(_settings.SigningCertificate),
                Subject = outgoingSubject,
                TokenIssuerName = _settings.IssuerUri,
                TokenType = validationResult.RelyingParty.TokenType
            };

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

            return CreateSupportedSecurityTokenHandler().CreateToken(descriptor);
        }
        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);
        }
        IHttpActionResult RedirectToLogin(CoreSettings settings, SignInValidationResult result)
        {
            var message = new SignInMessage();
            message.ReturnUrl = Request.RequestUri.AbsoluteUri;

            if (result.HomeRealm.IsPresent())
            {
                message.IdP = result.HomeRealm;
            }

            var url = LoginResult.GetRedirectUrl(message, this.Request, settings, _internalConfig);
            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 claims = await _users.GetProfileDataAsync(
                    validationResult.Subject);

                profileClaims = claims.ToList();
            }
            else
            {
                // get only claims that are explicitly mapped (if any)
                var claimTypes = validationResult.RelyingParty.ClaimMappings.Keys;

                if (claimTypes.Any())
                {
                    var claims = await _users.GetProfileDataAsync(
                        validationResult.Subject,
                        claimTypes);

                    profileClaims = claims.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 void LogError(string message, SignInValidationResult result)
 {
     var log = LogSerializer.Serialize(new SignInValidationLog(result));
     Logger.ErrorFormat("{0}\n{1}", message, log);
 }
 private void LogSuccess(SignInValidationResult result)
 {
     var log = LogSerializer.Serialize(new SignInValidationLog(result));
     Logger.InfoFormat("End WS-Federation signin request validation\n{0}", log);
 }
        IHttpActionResult RedirectToLogin(SignInValidationResult result)
        {
            var message = new SignInMessage();
            message.ReturnUrl = Request.RequestUri.AbsoluteUri;

            if (result.HomeRealm.IsPresent())
            {
                message.IdP = result.HomeRealm;
            }

            var url = LoginResult.GetRedirectUrl(message, this.Request.GetOwinContext().Environment, _wsFedOptions.DataProtector);
            return Redirect(url);
        }
Example #15
0
        private void LogError(string message, SignInValidationResult result)
        {
            var log = LogSerializer.Serialize(new SignInValidationLog(result));

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

            Logger.InfoFormat("End WS-Federation signin request validation\n{0}", log);
        }