예제 #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();
        }
        static public SessionSecurityToken ConvertSctToSessionToken(SecurityContextSecurityToken sct, SecureConversationVersion version)
        {
            string endpointId = String.Empty;

            for (int i = 0; i < sct.AuthorizationPolicies.Count; ++i)
            {
                EndpointAuthorizationPolicy epAuthPolicy = sct.AuthorizationPolicies[i] as EndpointAuthorizationPolicy;
                if (epAuthPolicy != null)
                {
                    endpointId = epAuthPolicy.EndpointId;
                    break;
                }
            }

            SctAuthorizationPolicy sctAuthPolicy = null;

            for (int i = 0; i < sct.AuthorizationPolicies.Count; i++)
            {
                IAuthorizationPolicy authPolicy = sct.AuthorizationPolicies[i];

                // The WCF SCT will have a SctAuthorizationPolicy that wraps the Primary Identity
                // of the bootstrap token. This is required for SCT renewal scenarios. Write the
                // SctAuthorizationPolicy if one is available.
                sctAuthPolicy = authPolicy as SctAuthorizationPolicy;
                if (sctAuthPolicy != null)
                {
                    break;
                }
            }

            ClaimsPrincipal claimsPrincipal = null;

            // these can be empty in transport security
            if (sct.AuthorizationPolicies != null && sct.AuthorizationPolicies.Count > 0)
            {
                AuthorizationPolicy ap = null;
                for (int i = 0; i < sct.AuthorizationPolicies.Count; ++i)
                {
                    ap = sct.AuthorizationPolicies[i] as AuthorizationPolicy;
                    if (ap != null)
                    {
                        // We should have exactly one IAuthorizationPolicy of type AuthorizationPolicy.
                        break;
                    }
                }
                if (ap != null)
                {
                    if (ap.IdentityCollection != null)
                    {
                        claimsPrincipal = new ClaimsPrincipal(ap.IdentityCollection);
                    }
                }
            }

            if (claimsPrincipal == null)
            {
                // When _securityContextTokenWrapper is true, this implies WCF.
                // Authpolicies not found occurs when the SCT represents a bootstrap nego that is used obtain a key
                // for the outer or actual SCT {unfortunate but true and we haven't found a way to distinguish this otherwise}.
                // So return an empty ClaimsPrincipal so that when written on wire in cookie mode we DO NOT write an empty identity.
                // If we did, then when the actual bootstrap token, such as a SAML token arrives, we will add the bootstrap AND the SAML identities to the ClaimsPrincipal
                // and end up with multiple, one of them anonymous.
                //
                claimsPrincipal = new ClaimsPrincipal();
            }

            return(new SessionSecurityToken(claimsPrincipal, sct.ContextId, sct.Id, String.Empty, sct.GetKeyBytes(), endpointId, sct.ValidFrom, sct.ValidTo, sct.KeyGeneration, sct.KeyEffectiveTime, sct.KeyExpirationTime, sctAuthPolicy, new Uri(version.Namespace.Value)));
        }