Beispiel #1
0
        /// <summary>
        /// The the purposes of this method are:
        /// 1. To enable layers above to get to the bootstrap tokens
        /// 2. To ensure an ClaimsPrincipal is inside the SCT authorization policies.  This is needed so that
        ///    a CustomPrincipal will be created and can be set.  This is required as we set the principal permission mode to custom
        /// 3. To set the IAuthorizationPolicy collection on the SCT to be one of IDFx's Authpolicy.
        /// This allows SCT cookie and SCT cached to be treated the same, futher up the stack.
        ///
        /// This method is call AFTER the final SCT has been created and the bootstrap tokens are around.  Itis not called during the SP/TLS nego bootstrap.
        /// </summary>
        /// <param name="sct"></param>
        internal void SetPrincipalBootstrapTokensAndBindIdfxAuthPolicy(SecurityContextSecurityToken sct)
        {
            if (sct == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sct");
            }

            List <IAuthorizationPolicy> iaps = new List <IAuthorizationPolicy>();

            //
            // The SecurityContextToken is cached first before the OnTokenIssued is called. So in the Session SCT
            // case the AuthorizationPolicies will have already been updated. So check the sct.AuthorizationPolicies
            // policy to see if the first is a AuthorizationPolicy.
            //
            if ((sct.AuthorizationPolicies != null) &&
                (sct.AuthorizationPolicies.Count > 0) &&
                (ContainsEndpointAuthPolicy(sct.AuthorizationPolicies)))
            {
                // We have already seen this sct and have fixed up the AuthorizationPolicy
                // collection. Just return.
                return;
            }

            //
            // Nego SCT just has a cookie, there are no IAuthorizationPolicy. In this case,
            // we want to add the EndpointAuthorizationPolicy alone to the SCT.
            //
            if ((sct.AuthorizationPolicies != null) &&
                (sct.AuthorizationPolicies.Count > 0))
            {
                //
                // Create a principal with known policies.
                //
                AuthorizationPolicy sctAp = IdentityModelServiceAuthorizationManager.TransformAuthorizationPolicies(sct.AuthorizationPolicies,
                                                                                                                    _securityTokenHandlerCollection,
                                                                                                                    false);
                // Replace the WCF authorization policies with our IDFx policies.
                // The principal is needed later on to set the custom principal by WCF runtime.
                iaps.Add(sctAp);

                //
                // Convert the claim from WCF unconditional policy to an SctAuthorizationPolicy. The SctAuthorizationPolicy simply
                // captures the primary identity claim from the WCF unconditional policy which IdFX will eventually throw away.
                // If we don't capture that claim, then in a token renewal scenario WCF will fail due to identities being different
                // for the issuedToken and the renewedToken.
                //
                SysClaim claim = GetPrimaryIdentityClaim(SystemAuthorizationContext.CreateDefaultAuthorizationContext(sct.AuthorizationPolicies));

                SctAuthorizationPolicy sctAuthPolicy = new SctAuthorizationPolicy(claim);
                iaps.Add(sctAuthPolicy);
            }

            iaps.Add(new EndpointAuthorizationPolicy(_endpointId));
            sct.AuthorizationPolicies = iaps.AsReadOnly();
        }
Beispiel #2
0
        /// <summary>
        /// Converts a given set of WCF IAuthorizationPolicy to WIF ClaimIdentities.
        /// </summary>
        /// <param name="authorizationPolicies">Set of AuthorizationPolicies to convert to IDFx.</param>
        /// <param name="securityTokenHandlerCollection">The SecurityTokenHandlerCollection to use.</param>
        /// <returns>ClaimsIdentityCollection</returns>
        static ReadOnlyCollection <ClaimsIdentity> ConvertToIDFxIdentities(IList <IAuthorizationPolicy> authorizationPolicies,
                                                                           SecurityTokenHandlerCollection securityTokenHandlerCollection)
        {
            if (authorizationPolicies == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("authorizationPolicies");
            }

            if (securityTokenHandlerCollection == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("securityTokenHandlerCollection");
            }

            List <ClaimsIdentity> identities = new List <ClaimsIdentity>();

            SecurityTokenSpecification kerberosTokenSpecification = null;
            SysAuthorizationContext    kerberosAuthContext        = null;

            if ((OperationContext.Current != null) &&
                (OperationContext.Current.IncomingMessageProperties != null) &&
                (OperationContext.Current.IncomingMessageProperties.Security != null))
            {
                SecurityMessageProperty securityMessageProperty = OperationContext.Current.IncomingMessageProperties.Security;
                foreach (SecurityTokenSpecification tokenSpecification in new SecurityTokenSpecificationEnumerable(securityMessageProperty))
                {
                    if (tokenSpecification.SecurityToken is KerberosReceiverSecurityToken)
                    {
                        kerberosTokenSpecification = tokenSpecification;
                        kerberosAuthContext        = SysAuthorizationContext.CreateDefaultAuthorizationContext(kerberosTokenSpecification.SecurityTokenPolicies);
                        break;
                    }
                }
            }

            bool hasKerberosTokenPolicyMatched = false;

            foreach (IAuthorizationPolicy policy in authorizationPolicies)
            {
                bool authPolicyHandled = false;

                if ((kerberosTokenSpecification != null) && !hasKerberosTokenPolicyMatched)
                {
                    if (kerberosTokenSpecification.SecurityTokenPolicies.Contains(policy))
                    {
                        hasKerberosTokenPolicyMatched = true;
                    }
                    else
                    {
                        SysAuthorizationContext authContext = SysAuthorizationContext.CreateDefaultAuthorizationContext(new List <IAuthorizationPolicy>()
                        {
                            policy
                        });
                        // Kerberos creates only one ClaimSet. So any more ClaimSet would mean that this is not a Policy created from Kerberos.
                        if (authContext.ClaimSets.Count == 1)
                        {
                            bool allClaimsMatched = true;
                            foreach (System.IdentityModel.Claims.Claim c in authContext.ClaimSets[0])
                            {
                                if (!kerberosAuthContext.ClaimSets[0].ContainsClaim(c))
                                {
                                    allClaimsMatched = false;
                                    break;
                                }
                            }
                            hasKerberosTokenPolicyMatched = allClaimsMatched;
                        }
                    }

                    if (hasKerberosTokenPolicyMatched)
                    {
                        SecurityTokenHandler tokenHandler = securityTokenHandlerCollection[kerberosTokenSpecification.SecurityToken];
                        if ((tokenHandler != null) && tokenHandler.CanValidateToken)
                        {
                            identities.AddRange(tokenHandler.ValidateToken(kerberosTokenSpecification.SecurityToken));
                            authPolicyHandled = true;
                        }
                    }
                }

                if (!authPolicyHandled)
                {
                    SysAuthorizationContext defaultAuthContext = SysAuthorizationContext.CreateDefaultAuthorizationContext(new List <IAuthorizationPolicy>()
                    {
                        policy
                    });
                    //
                    // Merge all ClaimSets to IClaimsIdentity.
                    //

                    identities.Add(ConvertToIDFxIdentity(defaultAuthContext.ClaimSets, securityTokenHandlerCollection.Configuration));
                }
            }

            return(identities.AsReadOnly());
        }
Beispiel #3
0
        /// <summary>
        /// Returns true if the IAuthorizationPolicy could have been created from the given Transport token.
        /// The method can handle only X509SecurityToken and WindowsSecurityToken.
        /// </summary>
        /// <param name="transportToken">Client's Security Token provided at the transport layer.</param>
        /// <param name="tranportTokenIdentities">A collection of <see cref="ClaimsIdentity"/> to match.</param>
        /// <param name="authPolicy">IAuthorizationPolicy to check.</param>
        /// <returns>True if the IAuthorizationPolicy could have been created from the given Transpor token.</returns>
        static bool DoesPolicyMatchTransportToken(
            SecurityToken transportToken,
            IEnumerable <ClaimsIdentity> tranportTokenIdentities,
            IAuthorizationPolicy authPolicy
            )
        {
            if (transportToken == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("transportToken");
            }

            if (tranportTokenIdentities == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tranportTokenIdentities");
            }

            if (authPolicy == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("authPolicy");
            }

            //////////////////////////////////////////////////////////////////////////////////////////
            //
            // There are 5 Client Authentication types at the transport layer. Each of these will
            // result either in a WindowsSecurityToken, X509SecurityToken or UserNameSecurityToken.
            //
            //      ClientCredential Type     ||        Transport Token Type
            // -------------------------------------------------------------------
            //          Basic                 ->        UserNameSecurityToken (In Self-hosted case)
            //          Basic                 ->        WindowsSecurityToken (In Web-Hosted case)
            //          NTLM                  ->        WindowsSecurityToken
            //          Negotiate             ->        WindowsSecurityToken
            //          Windows               ->        WindowsSecurityToken
            //          Certificate           ->        X509SecurityToken
            //
            //////////////////////////////////////////////////////////////////////////////////////////
            X509SecurityToken x509SecurityToken = transportToken as X509SecurityToken;

            SysAuthorizationContext defaultAuthContext = SysAuthorizationContext.CreateDefaultAuthorizationContext(new List <IAuthorizationPolicy>()
            {
                authPolicy
            });

            foreach (System.IdentityModel.Claims.ClaimSet claimset in defaultAuthContext.ClaimSets)
            {
                if (x509SecurityToken != null)
                {
                    // Check if the claimset contains a claim that matches the X.509 certificate thumbprint.
                    if (claimset.ContainsClaim(new System.IdentityModel.Claims.Claim(
                                                   System.IdentityModel.Claims.ClaimTypes.Thumbprint,
                                                   x509SecurityToken.Certificate.GetCertHash(),
                                                   System.IdentityModel.Claims.Rights.PossessProperty)))
                    {
                        return(true);
                    }
                }
                else
                {
                    // For WindowsSecurityToken and UserNameSecurityToken check that IClaimsdentity.Name
                    // matches the Name Claim in the ClaimSet.
                    // In most cases, we will have only one Identity in the ClaimsIdentityCollection
                    // generated from transport token.
                    foreach (ClaimsIdentity transportTokenIdentity in tranportTokenIdentities)
                    {
                        if (claimset.ContainsClaim(new System.IdentityModel.Claims.Claim(
                                                       System.IdentityModel.Claims.ClaimTypes.Name,
                                                       transportTokenIdentity.Name,
                                                       System.IdentityModel.Claims.Rights.PossessProperty), new ClaimStringValueComparer()))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }