/// <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))); }