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; }
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); }
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); }
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); }