예제 #1
0
        /// <summary>
        /// Finds a named collection of <see cref="SecurityKey"/>(s) that match the <see cref="SecurityKeyIdentifierClause"/> and returns a <see cref="NamedKeySecurityToken"/> that contains the <see cref="SecurityKey"/>(s).
        /// </summary>
        /// <param name="keyIdentifierClause">The <see cref="SecurityKeyIdentifier"/> to resolve to a <see cref="SecurityToken"/></param>
        /// <param name="token">The resolved <see cref="SecurityToken"/>.</param>
        /// <remarks>If there is no match, then <see cref="IssuerTokenResolver"/> and 'base' are called in order.</remarks>
        /// <returns>true if token was resolved.</returns>
        /// <exception cref="ArgumentNullException">if 'keyIdentifierClause' is null.</exception>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
            {
                throw new ArgumentNullException("keyIdentifierClause");
            }

            token = null;
            NamedKeySecurityKeyIdentifierClause namedKeyIdentifierClause = keyIdentifierClause as NamedKeySecurityKeyIdentifierClause;

            if (namedKeyIdentifierClause != null)
            {
                IList <SecurityKey> resolvedKeys = null;
                if (this.keys.TryGetValue(namedKeyIdentifierClause.Name, out resolvedKeys))
                {
                    token = new NamedKeySecurityToken(namedKeyIdentifierClause.Name, namedKeyIdentifierClause.Id, resolvedKeys);
                    return(true);
                }
            }

            if (IssuerTokenResolver != null && IssuerTokenResolver.TryResolveToken(keyIdentifierClause, out token))
            {
                return(true);
            }

            return(base.TryResolveTokenCore(keyIdentifierClause, out token));
        }
예제 #2
0
        public override ClaimsPrincipal ValidateToken(JWTSecurityToken jwt, TokenValidationParameters validationParameters)
        {
            Check.IsNotNull(jwt, "jwt");
            Check.IsNotNull(validationParameters, "validationParameters");

            diagnostics.WriteInformationTrace(TraceEventId.InboundParameters,
                                              "JWT token details from ACS: {0}, {1}, {2}, {3}",
                                              jwt.Issuer, jwt.ValidFrom, jwt.ValidTo, jwt.RawData);

            string audienceUrl;
            if (this.Configuration != null)
            {
                audienceUrl = this.Configuration.AudienceRestriction.AllowedAudienceUris[0].ToString();
            }
            else
            {
                audienceUrl = validationParameters.AllowedAudience;
            }
            
            // set up valid issuers
            if ((validationParameters.ValidIssuer == null) &&
                (validationParameters.ValidIssuers == null || !validationParameters.ValidIssuers.Any()))
            {
                List<string> issuers = new List<string>();
                issuers.AddRange(ConfigurationManager.AppSettings["Issuers"].Split(new[] { ',' }));
                validationParameters.ValidIssuers = issuers;
            }
            
            // setup signing token.
            if (validationParameters.SigningToken == null)
            {
                var resolver = (NamedKeyIssuerTokenResolver)this.Configuration.IssuerTokenResolver;
                if (resolver.SecurityKeys != null)
                {
                    List<SecurityKey> skeys;
                    if (resolver.SecurityKeys.TryGetValue(audienceUrl, out skeys))
                    {
                        var tok = new NamedKeySecurityToken(audienceUrl, skeys);
                        validationParameters.SigningToken = tok;
                    }
                }
            }

            diagnostics.WriteInformationTrace(TraceEventId.Flow, "Successfully validated JWT token from ACS");

            return base.ValidateToken(jwt, validationParameters);
        }
        /// <summary>
        /// Finds a named collection of <see cref="SecurityKey"/>(s) that match the <see cref="SecurityKeyIdentifierClause"/> and returns a <see cref="NamedKeySecurityToken"/> that contains the <see cref="SecurityKey"/>(s).
        /// </summary>
        /// <param name="keyIdentifierClause">The <see cref="SecurityKeyIdentifier"/> to resolve to a <see cref="SecurityToken"/></param>
        /// <param name="token">The resolved <see cref="SecurityToken"/>.</param>
        /// <remarks>If there is no match, then <see cref="IssuerTokenResolver"/> and 'base' are called in order.</remarks>
        /// <returns>true if token was resolved.</returns>
        /// <exception cref="ArgumentNullException">if 'keyIdentifierClause' is null.</exception>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
                throw new ArgumentNullException("keyIdentifierClause");

            token = null;
            NamedKeySecurityKeyIdentifierClause namedKeyIdentifierClause = keyIdentifierClause as NamedKeySecurityKeyIdentifierClause;
            if (namedKeyIdentifierClause != null)
            {
                IList<SecurityKey> resolvedKeys = null;
                if (this.keys.TryGetValue(namedKeyIdentifierClause.Name, out resolvedKeys))
                {
                    token = new NamedKeySecurityToken(namedKeyIdentifierClause.Name, namedKeyIdentifierClause.Id, resolvedKeys);
                    return true;
                }
            }

            if (IssuerTokenResolver != null && IssuerTokenResolver.TryResolveToken(keyIdentifierClause, out token))
            {
                return true;
            }

            return base.TryResolveTokenCore(keyIdentifierClause, out token);
        }
        public void NamedKeySecurityKeyIdentifierClause_Extensibility()
        {
            string clauseName = "kid";
            string keyId = Issuers.GotJwt;

            NamedKeySecurityKeyIdentifierClause clause = new NamedKeySecurityKeyIdentifierClause(clauseName, keyId);
            SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(clause);
            SigningCredentials signingCredentials = new SigningCredentials(KeyingMaterial.DefaultSymmetricSecurityKey_256, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest, keyIdentifier);
            JwtHeader jwtHeader = new JwtHeader(signingCredentials);
            SecurityKeyIdentifier ski = jwtHeader.SigningKeyIdentifier;
            Assert.AreEqual(ski.Count, 1, "ski.Count != 1 ");

            NamedKeySecurityKeyIdentifierClause clauseOut = ski.Find<NamedKeySecurityKeyIdentifierClause>();
            Assert.IsNotNull(clauseOut, "NamedKeySecurityKeyIdentifierClause not found");
            Assert.AreEqual(clauseOut.Name, clauseName, "clauseOut.Id != clauseId");
            Assert.AreEqual(clauseOut.Id, keyId, "clauseOut.KeyIdentifier != keyId");

            NamedKeySecurityToken NamedKeySecurityToken = new NamedKeySecurityToken(clauseName, keyId, new SecurityKey[] { KeyingMaterial.DefaultSymmetricSecurityKey_256 });
            Assert.IsTrue(NamedKeySecurityToken.MatchesKeyIdentifierClause(clause), "NamedKeySecurityToken.MatchesKeyIdentifierClause( clause ), failed");

            List<SecurityKey> list = new List<SecurityKey>() { KeyingMaterial.DefaultSymmetricSecurityKey_256 };
            Dictionary<string, IList<SecurityKey>> keys = new Dictionary<string, IList<SecurityKey>>() { { "kid", list }, };
            NamedKeyIssuerTokenResolver nkitr = new NamedKeyIssuerTokenResolver(keys: keys);
            SecurityKey sk = nkitr.ResolveSecurityKey(clause);
            Assert.IsNotNull(sk, "NamedKeySecurityToken.MatchesKeyIdentifierClause( clause ), failed");
        }
예제 #5
0
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Check.IsNotNull(request, "request");
            HttpStatusCode statusCode;
            string token;
          
            if (request.RequestUri.AbsolutePath.Contains("/authenticate"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (request.RequestUri.AbsolutePath.Contains("/signout"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (request.RequestUri.AbsolutePath.Contains("/SignOutCallback"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (request.RequestUri.AbsolutePath.Contains("/windowsLiveAuthorization"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (request.RequestUri.AbsolutePath.Contains("api/GetSupportedIdentityProviders"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (request.RequestUri.AbsolutePath.Contains("api/SignInCallBack"))
            {
                return base.SendAsync(request, cancellationToken);
            }

            if (!TryRetrieveToken(request, out token))
            {
                statusCode = HttpStatusCode.Unauthorized;
                return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode));
            }

            try
            {
                diagnostics.WriteInformationTrace(TraceEventId.Flow, "Validating bearer token: {0}", token);

                string issuersValue = ConfigurationManager.AppSettings["Issuers"];
                string signingSymmetricKey = ConfigurationManager.AppSettings["SigningSymmetricKey"];
                string allowedAudience = ConfigurationManager.AppSettings["AllowedAudience"];

                // Use JWTSecurityTokenHandler to validate the JWT token
                ApiJWTSecurityTokenHandler tokenHandler = new ApiJWTSecurityTokenHandler();

                List<string> issuers = new List<string>();
                issuers.AddRange(issuersValue.Split(new[] { ',' }));

                InMemorySymmetricSecurityKey securityKey = new InMemorySymmetricSecurityKey(Convert.FromBase64String(signingSymmetricKey));

                NamedKeySecurityToken namedToken = new NamedKeySecurityToken(allowedAudience, new List<SecurityKey>() { securityKey });

                // Set the expected properties of the JWT token in the TokenValidationParameters
                TokenValidationParameters validationParameters = new TokenValidationParameters()
                {
                    AllowedAudience = allowedAudience,
                    ValidIssuers = issuers,
                    SigningToken = namedToken
                };

                ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(token, validationParameters);
                ClaimsIdentity claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;
                try
                {
                    IUserService userService = (IUserService)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserService));
                    User user = IdentityHelper.GetCurrentUser(userService, claimsPrincipal);
                    foreach (var role in user.UserRoles)
                    {
                        if (!claimsIdentity.HasClaim(ClaimTypes.Role, role.Role.Name))
                        {
                            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role.Role.Name));
                        }
                    }
                }
                catch (UserNotFoundException)
                {
                    // No need to do anything here because GetUsersByNameIdentifier action in UsersController will take care of sending appropriate http response.
                }

                Thread.CurrentPrincipal = claimsPrincipal;
                if (HttpContext.Current != null)
                {
                    HttpContext.Current.User = claimsPrincipal;
                }

                diagnostics.WriteInformationTrace(TraceEventId.Flow,
                                        "Authorization token validated successfully");

                return base.SendAsync(request, cancellationToken);
            }
            catch (SecurityTokenValidationException secutiryTokenValidationException)
            {
                FederatedAuthentication.WSFederationAuthenticationModule.SignOut(true);
                HttpResponseMessage response = request.CreateErrorResponse(HttpStatusCode.Unauthorized, secutiryTokenValidationException);
                return Task<HttpResponseMessage>.Factory.StartNew(() => response);
            }
        }