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;
 }
Example #3
0
        /// <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;
            }
        }