protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation) { TlsSspiNegotiation tlsNegotiation = (TlsSspiNegotiation)sspiNegotiation; if (tlsNegotiation.IsValidContext == false) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation))); } if (this.ClientTokenAuthenticator == null) { return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance; } X509Certificate2 clientCertificate = tlsNegotiation.RemoteCertificate; if (clientCertificate == null) { // isAnonymous is false. So, fail the negotiation throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityTokenValidationException(SR.GetString(SR.ClientCertificateNotProvided))); } ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies; if (this.ClientTokenAuthenticator != null) { X509SecurityToken clientToken; WindowsIdentity preMappedIdentity; if (!this.MapCertificateToWindowsAccount || !tlsNegotiation.TryGetContextIdentity(out preMappedIdentity)) { clientToken = new X509SecurityToken(clientCertificate); } else { clientToken = new X509WindowsSecurityToken(clientCertificate, preMappedIdentity, preMappedIdentity.AuthenticationType, true); preMappedIdentity.Dispose(); } authorizationPolicies = this.ClientTokenAuthenticator.ValidateToken(clientToken); clientToken.Dispose(); } else { authorizationPolicies = EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance; } return authorizationPolicies; }
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation) { X509SecurityToken token; WindowsIdentity identity; TlsSspiNegotiation negotiation = (TlsSspiNegotiation) sspiNegotiation; if (!negotiation.IsValidContext) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(System.ServiceModel.SR.GetString("InvalidSspiNegotiation"))); } if (this.ClientTokenAuthenticator == null) { return System.ServiceModel.Security.EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance; } X509Certificate2 remoteCertificate = negotiation.RemoteCertificate; if (remoteCertificate == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityTokenValidationException(System.ServiceModel.SR.GetString("ClientCertificateNotProvided"))); } if (this.ClientTokenAuthenticator == null) { return System.ServiceModel.Security.EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance; } if (!this.MapCertificateToWindowsAccount || !negotiation.TryGetContextIdentity(out identity)) { token = new X509SecurityToken(remoteCertificate); } else { token = new X509WindowsSecurityToken(remoteCertificate, identity, identity.AuthenticationType, true); identity.Dispose(); } ReadOnlyCollection<IAuthorizationPolicy> onlys = this.ClientTokenAuthenticator.ValidateToken(token); token.Dispose(); return onlys; }
/// <summary> /// Validates an <see cref="X509SecurityToken"/>. /// </summary> /// <param name="token">The <see cref="X509SecurityToken"/> to validate.</param> /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities contained in the token.</returns> /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception> /// <exception cref="ArgumentException">The token is not assignable from <see cref="X509SecurityToken"/>.</exception> /// <exception cref="InvalidOperationException">Configuration <see cref="SecurityTokenHandlerConfiguration"/>is null.</exception> /// <exception cref="SecurityTokenValidationException">The current <see cref="X509CertificateValidator"/> was unable to validate the certificate in the Token.</exception> /// <exception cref="InvalidOperationException">Configuration.IssuerNameRegistry is null.</exception> /// <exception cref="SecurityTokenException">Configuration.IssuerNameRegistry return null when resolving the issuer of the certificate in the Token.</exception> public override ReadOnlyCollection <ClaimsIdentity> ValidateToken(SecurityToken token) { if (token == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token"); } X509SecurityToken x509Token = token as X509SecurityToken; if (x509Token == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(X509SecurityToken))); } if (this.Configuration == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4274)); } try { // Validate the token. try { this.CertificateValidator.Validate(x509Token.Certificate); } catch (SecurityTokenValidationException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.ID4257, X509Util.GetCertificateId(x509Token.Certificate)), e)); } if (this.Configuration.IssuerNameRegistry == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4277)); } string issuer = X509Util.GetCertificateIssuerName(x509Token.Certificate, this.Configuration.IssuerNameRegistry); if (String.IsNullOrEmpty(issuer)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4175))); } ClaimsIdentity identity = null; if (!mapToWindows) { identity = new ClaimsIdentity(AuthenticationTypes.X509); // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical. identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.X509)); } else { WindowsIdentity windowsIdentity; X509WindowsSecurityToken x509WindowsSecurityToken = token as X509WindowsSecurityToken; // if this is the case, then the user has already been mapped to a windows account, just return the identity after adding a couple of claims. if (x509WindowsSecurityToken != null && x509WindowsSecurityToken.WindowsIdentity != null) { // X509WindowsSecurityToken is disposable, make a copy. windowsIdentity = new WindowsIdentity(x509WindowsSecurityToken.WindowsIdentity.Token, x509WindowsSecurityToken.AuthenticationType); } else { // Ensure NT_AUTH chain policy for certificate account mapping if (this.x509NTAuthChainTrustValidator == null) { lock (this.lockObject) { if (this.x509NTAuthChainTrustValidator == null) { this.x509NTAuthChainTrustValidator = new X509NTAuthChainTrustValidator(); } } } this.x509NTAuthChainTrustValidator.Validate(x509Token.Certificate); windowsIdentity = ClaimsHelper.CertificateLogon(x509Token.Certificate); } // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical. windowsIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.X509)); identity = windowsIdentity; } if (this.Configuration.SaveBootstrapContext) { identity.BootstrapContext = new BootstrapContext(token, this); } identity.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(DateTime.UtcNow, DateTimeFormats.Generated), ClaimValueTypes.DateTime)); identity.AddClaims(X509Util.GetClaimsFromCertificate(x509Token.Certificate, issuer)); this.TraceTokenValidationSuccess(token); List <ClaimsIdentity> identities = new List <ClaimsIdentity>(1); identities.Add(identity); return(identities.AsReadOnly()); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } this.TraceTokenValidationFailure(token, e.Message); throw e; } }