Esempio n. 1
0
        // Assert that returned token pair is valid
        private void checkActionResult(IActionResult actionResult, JwtIssuerOptions jwtIssuerOptions, SymmetricSecurityKey signingKey)
        {
            var actionResultType = actionResult.GetType().ToString();

            Assert.Equal("Microsoft.AspNetCore.Mvc.OkObjectResult", actionResultType);

            // I should get back two tokens as json objects
            var typedActionResult = actionResult as Microsoft.AspNetCore.Mvc.OkObjectResult;

            Assert.NotNull(typedActionResult);
            if (typedActionResult == null)
            {
                return;
            }

            string body = typedActionResult.Value as string;

            Assert.NotNull(body);
            if (body == null)
            {
                return;
            }

            dynamic objResponses  = null;
            bool    bDeserialized = true;

            try
            {
                objResponses = JsonConvert.DeserializeObject <List <dynamic> >(body);
            }
            catch
            {
                bDeserialized = false;
            }

            Assert.True(bDeserialized);
            if (!bDeserialized)
            {
                return;
            }

            // objResponses should be a list of dynamic objects, the first of
            // which should be an access token, the second of which should be
            // a refresh token
            int count = 0;

            foreach (var objResponse in objResponses)
            {
                count++;
            }

            Assert.Equal(2, count);
            if (count != 2)
            {
                return;
            }

            var objResponse0 = objResponses[0]; // Access token wrapper
            var objResponse1 = objResponses[1]; // Refresh token wrapper

            string sAccessToken      = AppUtility.GetDynamicPropertyValueAsString(objResponse0, "access_token");
            string sRefreshToken     = AppUtility.GetDynamicPropertyValueAsString(objResponse1, "refresh_token");
            Int64  iAccessExpiresIn  = AppUtility.GetDynamicPropertyValueAsInt64(objResponse0, "expires_in", -1);
            Int64  iRefreshExpiresIn = AppUtility.GetDynamicPropertyValueAsInt64(objResponse1, "expires_in", -1);

            // Token strings should not be empty
            Assert.NotEqual(0, sAccessToken.Length);
            Assert.NotEqual(0, sRefreshToken.Length);

            // Expires values should not be null, Refresh value should always be greater than Access value
            Assert.True(iAccessExpiresIn > 0);
            Assert.True(iRefreshExpiresIn > 0);
            Assert.True(iRefreshExpiresIn > iAccessExpiresIn);

            // I should be able to decode those tokens, using the known secrets
            // and confirm that the details in the tokens are correct

            var handler = new JwtSecurityTokenHandler();

            var accessTokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer           = true,
                ValidIssuer              = jwtIssuerOptions.Issuer,
                ValidateAudience         = true,
                ValidAudience            = jwtIssuerOptions.Audience,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = signingKey,
                RequireExpirationTime    = true,
                ValidateLifetime         = true,
                ClockSkew = TimeSpan.FromSeconds(jwtIssuerOptions.AccessClockSkew)
            };

            var refreshTokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer           = true,
                ValidIssuer              = jwtIssuerOptions.Issuer,
                ValidateAudience         = true,
                ValidAudience            = jwtIssuerOptions.Audience,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = signingKey,
                RequireExpirationTime    = true,
                ValidateLifetime         = true,
                ClockSkew = TimeSpan.FromSeconds(jwtIssuerOptions.RefreshClockSkew)
            };

            SecurityToken validatedRefreshToken  = null;
            var           refreshClaimsPrincipal = handler.ValidateToken(sRefreshToken, refreshTokenValidationParameters, out validatedRefreshToken);

            Assert.NotNull(validatedRefreshToken);

            SecurityToken validatedAccessToken  = null;
            var           accessClaimsPrincipal = handler.ValidateToken(sAccessToken, accessTokenValidationParameters, out validatedAccessToken);

            Assert.NotNull(validatedAccessToken);

            // Cast to JwtSecurityToken
            var validatedRefreshJwtSecurityToken = validatedRefreshToken as JwtSecurityToken;

            Assert.NotNull(validatedRefreshJwtSecurityToken);

            var validatedAccessJwtSecurityToken = validatedAccessToken as JwtSecurityToken;

            Assert.NotNull(validatedAccessJwtSecurityToken);


            // AccessClaimsPrincipal should have
            //  Identies collection count of 1
            //  Identity with Name property of Alice
            //  Identity property with some claims, including role of "User"

            int countIdentitiesA = 0;

            foreach (var possibleIdentityA in accessClaimsPrincipal.Identities)
            {
                ++countIdentitiesA;
            }
            Assert.Equal(1, countIdentitiesA);
            Assert.Equal("Alice", accessClaimsPrincipal.Identity.Name);

            int countClaimsA = 0;

            foreach (var possibleClaimA in accessClaimsPrincipal.Claims)
            {
                ++countClaimsA;
            }
            Assert.Equal(9, countClaimsA);

            Assert.True(accessClaimsPrincipal.HasClaim(ClaimTypes.Role, "User"));
            Assert.True(accessClaimsPrincipal.HasClaim(ClaimTypes.Name, "Alice"));


            // RefreshClaimsPrincipal should have Name, Guid and IP to validate against database.
            // Name and Guid may be strings, IP may be empty.

            int countIdentitiesR = 0;

            foreach (var possibleIdentityR in refreshClaimsPrincipal.Identities)
            {
                ++countIdentitiesR;
            }
            Assert.Equal(1, countIdentitiesR);

            int countClaimsR = 0;

            foreach (var possibleClaimR in refreshClaimsPrincipal.Claims)
            {
                ++countClaimsR;
            }
            Assert.Equal(6, countClaimsR);

            Assert.True(refreshClaimsPrincipal.HasClaim(c => c.Type == JwtController.GUIDKEY));
            Assert.True(refreshClaimsPrincipal.HasClaim(JwtController.NAMEKEY, "Alice"));
            Assert.True(refreshClaimsPrincipal.HasClaim(c => c.Type == JwtController.IPKEY));
        }