private SignInResponseMessage CreateResponse(SignInValidationResult validationResult, SecurityToken token) { var rstr = new RequestSecurityTokenResponse { AppliesTo = new EndpointReference(validationResult.Client.ClientId), Context = validationResult.SignInRequestMessage.Context, ReplyTo = validationResult.ReplyUrl, RequestedSecurityToken = new RequestedSecurityToken(token) }; //var serializer = new WSFederationSerializer( // new WSTrust13RequestSerializer(), // new WSTrust13ResponseSerializer()); // the asp.net core MW does currently not support WS-Trust 1.3 var serializer = new WSFederationSerializer( new WSTrustFeb2005RequestSerializer(), new WSTrustFeb2005ResponseSerializer()); var mgr = SecurityTokenHandlerCollectionManager.CreateEmptySecurityTokenHandlerCollectionManager(); mgr[SecurityTokenHandlerCollectionManager.Usage.Default] = CreateSupportedSecurityTokenHandler(); var responseMessage = new SignInResponseMessage( new Uri(validationResult.ReplyUrl), rstr, serializer, new WSTrustSerializationContext(mgr)); return(responseMessage); }
public async Task <string> GenerateSerializedRstr(ValidatedWsFederationSigninRequest request) { var now = _clock.UtcNow.UtcDateTime; var principal = request.Subject.Identity as ClaimsIdentity; var nameIdClaim = principal.FindFirst(ClaimTypes.NameIdentifier); if (nameIdClaim == null) { nameIdClaim = new Claim(ClaimTypes.NameIdentifier, principal.Name); nameIdClaim.Properties.Add(ClaimProperties.SamlNameIdentifierFormat, Saml2Constants.NameIdentifierFormats.UnspecifiedString); principal.AddClaim(nameIdClaim); } var tokenDescriptor = new SecurityTokenDescriptor { Audience = request.RequestMessage.Wtrealm, Expires = now.AddSeconds(request.Client.IdentityTokenLifetime), IssuedAt = now, Issuer = _options.IssuerUri, NotBefore = now, SigningCredentials = await _keys.GetSigningCredentialsAsync(), Subject = principal }; //For whatever reason, the Digest method isn't specified in the builder extensions for identity server. //Not a good solution to force the user to use th eoverload that takes SigningCredentials //IdentityServer4/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs //Instead, it should be supported in: // The overload that takes a X509Certificate2 // The overload that looks it up in a cert store // The overload that takes an RsaSecurityKey // AddDeveloperSigningCredential //For now, this is a workaround. if (tokenDescriptor.SigningCredentials.Digest == null) { _logger.LogInformation($"SigningCredentials does not have a digest specified. Using default digest algorithm of {SecurityAlgorithms.Sha256Digest}"); tokenDescriptor.SigningCredentials = new SigningCredentials(tokenDescriptor.SigningCredentials.Key, tokenDescriptor.SigningCredentials.Algorithm, SecurityAlgorithms.Sha256Digest); } _logger.LogDebug("Creating SAML 2.0 security token."); var tokenHandler = new Saml2SecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); _logger.LogDebug("Serializing RSTR."); var rstr = new RequestSecurityTokenResponse { AppliesTo = new AppliesTo(request.RequestMessage.Wtrealm), KeyType = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey", Lifetime = new Lifetime(now, now.AddSeconds(request.Client.IdentityTokenLifetime)), RequestedSecurityToken = token, RequestType = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue", TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" }; return(RequestSecurityTokenResponseSerializer.Serialize(rstr)); }
public async Task <string> GenerateSerializedRstr(ValidatedWsFederationRequest request) { var now = _clock.UtcNow.UtcDateTime; var credential = await _keys.GetSigningCredentialsAsync(); var key = credential.Key as X509SecurityKey; var tokenDescriptor = new SecurityTokenDescriptor { Audience = request.RequestMessage.Wtrealm, Expires = now.AddSeconds(request.Client.IdentityTokenLifetime), IssuedAt = now, Issuer = _options.IssuerUri, NotBefore = now, SigningCredentials = key == null ? credential : new X509SigningCredentials(key.Certificate, _federationOptions.DefaultSignatureAlgorithm), Subject = await CreateSubjectAsync(request) }; //For whatever reason, the Digest method isn't specified in the builder extensions for identity server. //Not a good solution to force the user to use the overload that takes SigningCredentials //IdentityServer4/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs //Instead, it should be supported in: // The overload that takes a X509Certificate2 // The overload that looks it up in a cert store // The overload that takes an RsaSecurityKey // AddDeveloperSigningCredential //For now, this is a workaround. if (tokenDescriptor.SigningCredentials.Digest == null) { _logger.LogInformation($"SigningCredentials does not have a digest specified. Using default digest algorithm of {SecurityAlgorithms.Sha256Digest}"); tokenDescriptor.SigningCredentials = new SigningCredentials(tokenDescriptor.SigningCredentials.Key, tokenDescriptor.SigningCredentials.Algorithm ?? _federationOptions.DefaultSignatureAlgorithm, _federationOptions.DefaultDigestAlgorithm); } _logger.LogDebug("Creating SAML 2.0 security token."); var tokenHandler = new Saml2SecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); _logger.LogDebug("Serializing RSTR."); var rstr = new RequestSecurityTokenResponse { AppliesTo = new AppliesTo(request.RequestMessage.Wtrealm), KeyType = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey", Lifetime = new Lifetime { Created = XmlConvert.ToString(now, XmlDateTimeSerializationMode.Utc), Expires = XmlConvert.ToString(now.AddSeconds(request.Client.IdentityTokenLifetime), XmlDateTimeSerializationMode.Utc), }, RequestedSecurityToken = token, RequestType = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue", TokenType = WsFederationConstants.TokenTypes.Saml2TokenProfile11 }; return(RequestSecurityTokenResponseSerializer.Serialize(rstr)); }
private WsFederationMessage CreateResponse(SignInValidationResult validationResult, SecurityToken token) { var handler = CreateTokenHandler(validationResult.RelyingParty.TokenType); var rstr = new RequestSecurityTokenResponse { CreatedAt = token.ValidFrom, ExpiresAt = token.ValidTo, AppliesTo = validationResult.Client.ClientId, Context = validationResult.WsFederationMessage.Wctx, ReplyTo = validationResult.ReplyUrl, RequestedSecurityToken = token, SecurityTokenHandler = handler, }; var responseMessage = new WsFederationMessage { IssuerAddress = validationResult.Client.RedirectUris.First(), Wa = Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConstants.WsFederationActions.SignIn, Wresult = rstr.Serialize(), Wctx = validationResult.WsFederationMessage.Wctx }; return(responseMessage); }