protected virtual async ValueTask <WsTrustSecurityTokenDescriptor> CreateSecurityTokenDescriptorAsync(WsTrustRequest request, Scope scope, CancellationToken cancellationToken) { var lifetime = CreateTokenLifetime(request?.Lifetime, scope); var descriptor = new WsTrustSecurityTokenDescriptor { Audience = scope.RelyingParty.AppliesTo, IssuedAt = lifetime.Created, Expires = lifetime.Expires, Issuer = scope.RelyingParty.ExpectedIssuer ?? Options.Issuer, SigningCredentials = scope.SigningCredentials, EncryptingCredentials = scope.RelyingParty.RequiresEncryptedToken ? scope.EncryptingCredentials : null, ProofKeyEncryptingCredentials = scope.RelyingParty.RequiresEncryptedSymmetricKeys ? scope.EncryptingCredentials : null, TokenType = request.TokenType }; if (lifetime.Created != null) { descriptor.NotBefore = lifetime.Created.Value.Subtract(scope.RelyingParty.ClockSkew ?? Options.MaxClockSkew); } var requestorProofEncryptingCredentials = await GetRequestorProofEncryptingCredentialsAsync(request, cancellationToken); if (requestorProofEncryptingCredentials != null) { descriptor.ProofKeyEncryptingCredentials = requestorProofEncryptingCredentials; } descriptor.ProofKey = await CreateProofKeyAsync(request, scope, descriptor, cancellationToken); return(descriptor); }
protected virtual async ValueTask <SecurityKey> CreateProofKeyAsync(WsTrustRequest request, Scope scope, WsTrustSecurityTokenDescriptor descriptor, CancellationToken cancellationToken) { var keyType = request.KeyType; // asymmetric and psha1 // not supported at this moment if (keyType == Constants.WsTrustKeyTypes.PublicKey || keyType == Constants.WsTrustKeyTypes.PSHA1) { throw new NotSupportedException($"Key type '{keyType}' not supported at this time."); } if (keyType == Constants.WsTrustKeyTypes.Bearer) { return(null); } // symmetric if (request.ComputedKeyAlgorithm != null && request.ComputedKeyAlgorithm != "http://schemas.microsoft.com/idfx/computedkeyalgorithm/psha1") { throw new NotSupportedException($"Computed key algortihm '{request.ComputedKeyAlgorithm}' not supported at this time."); } if (descriptor.ProofKeyEncryptingCredentials == null && scope.RelyingParty.RequiresEncryptedSymmetricKeys) { throw new InvalidOperationException("Cannot created proof token with no encrypting credentials."); } if (scope.EncryptingCredentials == null && scope.RelyingParty.RequiresEncryptedToken) { throw new InvalidOperationException("Missing encrypting credentials."); } return(await CreateSymmetricProofKeyAsync(request.KeySizeInBits.Value)); }
protected virtual async ValueTask <WsTrustResponse> CreateResponseAsync(WsTrustRequest request, WsTrustSecurityTokenDescriptor descriptor, CancellationToken cancellationToken) { if (descriptor == null) { return(null); } var response = new RequestSecurityTokenResponse(); var handler = await GetSecurityTokenHandlerAsync(request.TokenType, cancellationToken); try { var attached = handler.CreateSecurityTokenReference(descriptor.Token, true); if (attached is WsSecuritySecurityKeyIdentifierClause attachedClause) { descriptor.AttachedReference = attachedClause.CreateReference(); } var unattached = handler.CreateSecurityTokenReference(descriptor.Token, false); if (unattached is WsSecuritySecurityKeyIdentifierClause unattachedClause) { descriptor.UnattachedReference = unattachedClause.CreateReference(); } } catch { } descriptor.ApplyTo(response); if (!string.IsNullOrEmpty(request.Context)) { response.Context = request.Context; } if (!string.IsNullOrEmpty(request.KeyType)) { response.KeyType = request.KeyType; } if (request.KeySizeInBits > 0 && IsSupportedAsymmetricKeyType(request.KeyType)) { response.KeySizeInBits = request.KeySizeInBits; } // no replyto //if (request.ReplyTo != null) // response.ReplyTo = descriptor.ReplyToAddress; if (!string.IsNullOrEmpty(descriptor.Audience)) { response.AppliesTo = new AppliesTo(new EndpointReference(descriptor.Audience)); } var proofToken = await CreateRequestedProofTokenAsync(descriptor, cancellationToken); if (proofToken != null) { response.RequestedProofToken = proofToken; } return(new WsTrustResponse(response)); }
protected virtual ValueTask <RequestedProofToken> CreateRequestedProofTokenAsync(WsTrustSecurityTokenDescriptor descriptor, CancellationToken cancellationToken) { if (descriptor.ProofKey == null) { return(new ValueTask <RequestedProofToken>()); } if (!(descriptor.ProofKey is SymmetricSecurityKey symmetric)) { throw new NotSupportedException($"Asymmetric proof keys not supported for now."); } // The microsoft ws-trust serializer can't handle encrypted RequestedProofToken. Hard code unencrypted for now. var secret = new BinarySecret(symmetric.Key, Constants.WsTrustKeyTypes.Symmetric); return(new ValueTask <RequestedProofToken>(new RequestedProofToken(secret))); }
protected virtual ValueTask <SecurityToken> CreateSecurityTokenAsync(Scope scope, WsTrustRequest request, WsTrustSecurityTokenDescriptor descriptor, SecurityTokenHandler handler, CancellationToken cancellationToken) => new ValueTask <SecurityToken>(handler.CreateToken(descriptor));