예제 #1
0
        public void JwtController_Refresh_HandlesBadInput()
        {
            ///////////////////////////////////////////////////////////////////
            // Arrange
            //

            //   Options
            string secret = "A_KEY_MUST_BE_16_CHARS+";
            SymmetricSecurityKey signingKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret.PadRight(16)));
            SigningCredentials   signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

            var jwtIssuerOptions = new JwtIssuerOptions
            {
                Issuer             = "TokenIssuer",
                Audience           = "TokenAudience",
                AccessValidFor     = TimeSpan.FromSeconds(10),
                RefreshValidFor    = TimeSpan.FromSeconds(100),
                AccessClockSkew    = 0,
                RefreshClockSkew   = 0,
                Subject            = "Alice",
                SigningCredentials = signingCredentials
            };

            var mockOptions = new Mock <IOptions <JwtIssuerOptions> >();

            mockOptions.Setup(mo => mo.Value).Returns(jwtIssuerOptions);

            //   UserManager
            var fakeUserManager = new FakeUserManager();

            //   TokenStore
            var tokenStore = new ExampleTokenStore();

            //   Configuration
            var mockConfiguration = new Mock <IConfiguration>();

            mockConfiguration.SetupGet(m => m[Constants.SECRET_ENV_VAR]).Returns(secret);

            //   Logger
            var mockLogger = new Mock <ILogger <JwtController> >();

            JwtController controller = new JwtController(mockOptions.Object, fakeUserManager, tokenStore, mockConfiguration.Object, mockLogger.Object);


            // Act & Assert
            var actionResult = controller.Refresh(null);

            Assert.Equal("Microsoft.AspNetCore.Mvc.BadRequestObjectResult", actionResult.Result.GetType().ToString());

            actionResult = controller.Refresh("TotalGarbage");
            Assert.Equal("Microsoft.AspNetCore.Mvc.BadRequestObjectResult", actionResult.Result.GetType().ToString());

            actionResult = controller.Refresh("");
            Assert.Equal("Microsoft.AspNetCore.Mvc.BadRequestObjectResult", actionResult.Result.GetType().ToString());
        }
예제 #2
0
        public void JwtController_CanIssueAndRefreshTokens()
        {
            ///////////////////////////////////////////////////////////////////
            // Arrange
            //

            //   Options
            string secret = "A_KEY_MUST_BE_16_CHARS+";
            SymmetricSecurityKey signingKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret.PadRight(16)));
            SigningCredentials   signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

            var jwtIssuerOptions = new JwtIssuerOptions
            {
                Issuer             = "TokenIssuer",
                Audience           = "TokenAudience",
                AccessValidFor     = TimeSpan.FromSeconds(10),
                RefreshValidFor    = TimeSpan.FromSeconds(100),
                AccessClockSkew    = 0,
                RefreshClockSkew   = 0,
                Subject            = "Alice",
                SigningCredentials = signingCredentials
            };

            var mockOptions = new Mock <IOptions <JwtIssuerOptions> >();

            mockOptions.Setup(mo => mo.Value).Returns(jwtIssuerOptions);

            //   UserManager
            var fakeUserManager = new FakeUserManager();

            //   TokenStore
            var tokenStore = new ExampleTokenStore();

            //   Configuration
            var mockConfiguration = new Mock <IConfiguration>();

            mockConfiguration.SetupGet(m => m[Constants.SECRET_ENV_VAR]).Returns(secret);

            //   Logger
            var mockLogger = new Mock <ILogger <JwtController> >();

            JwtController controller = new JwtController(mockOptions.Object, fakeUserManager, tokenStore, mockConfiguration.Object, mockLogger.Object);

            // Credentials
            LoginCredentials creds = new LoginCredentials {
                UserName = "******", Password = "******"
            };



            ///////////////////////////////////////////////////////////////////
            // Act
            //

            var issueResult = controller.Issue(creds);

            var typedActionIssueResult = issueResult.Result as Microsoft.AspNetCore.Mvc.OkObjectResult;

            Assert.NotNull(typedActionIssueResult);

            string issueBody = typedActionIssueResult.Value as string;

            Assert.NotNull(issueBody);

            dynamic objResponses  = null;
            bool    bDeserialized = true;

            try
            {
                objResponses = JsonConvert.DeserializeObject <List <dynamic> >(issueBody);
            }
            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
            var objResponse0 = objResponses[0]; // Access token wrapper
            var objResponse1 = objResponses[1]; // Refresh token wrapper

            string sRefreshToken = AppUtility.GetDynamicPropertyValueAsString(objResponse1, "refresh_token");

            // Call the Refresh endpoint with the token to see if a new pair of tokens are issued.

            var refreshResult = controller.Refresh(sRefreshToken);

            checkActionResult(refreshResult.Result, jwtIssuerOptions, signingKey);
        }
예제 #3
0
        public void JwtController_RefreshTokenClockSkewWorks()
        {
            ///////////////////////////////////////////////////////////////////
            // Arrange
            //

            //   Options
            string secret = "A_KEY_MUST_BE_16_CHARS+";
            SymmetricSecurityKey signingKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret.PadRight(16)));
            SigningCredentials   signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

            /////////////////////////
            int    iAccessValidFor   = 3;
            int    iRefreshValidFor  = 6; // <- Short refresh time for testing
            UInt32 iRefreshClockSkew = 5;
            /////////////////////////

            var jwtIssuerOptions = new JwtIssuerOptions
            {
                Issuer             = "TokenIssuer",
                Audience           = "TokenAudience",
                AccessValidFor     = TimeSpan.FromSeconds(iAccessValidFor),
                RefreshValidFor    = TimeSpan.FromSeconds(iRefreshValidFor),
                AccessClockSkew    = 0,
                RefreshClockSkew   = iRefreshClockSkew,
                Subject            = "Alice",
                SigningCredentials = signingCredentials
            };

            var mockOptions = new Mock <IOptions <JwtIssuerOptions> >();

            mockOptions.Setup(mo => mo.Value).Returns(jwtIssuerOptions);

            //   UserManager
            var fakeUserManager = new FakeUserManager();

            //   TokenStore
            var tokenStore = new ExampleTokenStore();

            //   Configuration
            var mockConfiguration = new Mock <IConfiguration>();

            mockConfiguration.SetupGet(m => m[Constants.SECRET_ENV_VAR]).Returns(secret);

            //   Logger
            var mockLogger = new Mock <ILogger <JwtController> >();

            JwtController controller = new JwtController(mockOptions.Object, fakeUserManager, tokenStore, mockConfiguration.Object, mockLogger.Object);

            // Credentials
            LoginCredentials creds = new LoginCredentials {
                UserName = "******", Password = "******"
            };



            ///////////////////////////////////////////////////////////////////
            // Act
            //

            var issueResult = controller.Issue(creds);

            var typedActionIssueResult = issueResult.Result as Microsoft.AspNetCore.Mvc.OkObjectResult;

            Assert.NotNull(typedActionIssueResult);

            string issueBody = typedActionIssueResult.Value as string;

            Assert.NotNull(issueBody);

            dynamic objResponses  = null;
            bool    bDeserialized = true;

            try
            {
                objResponses = JsonConvert.DeserializeObject <List <dynamic> >(issueBody);
            }
            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
            var objResponse0 = objResponses[0]; // Access token wrapper
            var objResponse1 = objResponses[1]; // Refresh token wrapper

            string sRefreshToken = AppUtility.GetDynamicPropertyValueAsString(objResponse1, "refresh_token");

            // ALLOW TIME TO ELAPSE SO THAT THE REFRESH TOKEN IS STALE IF
            // ZERO CLOCK SKEW, BUT JUST ABOUT ACCEPTABLE IF CLOCK SKEW IS WORKING
            System.Threading.Thread.Sleep(1000 * (iRefreshValidFor + (int)iRefreshClockSkew - 2)); // Sleep for at least the timeout time of the refresh token, plus 1 second

            // Call the Refresh endpoint with the token to see if a new pair of tokens are issued.
            var refreshResult = controller.Refresh(sRefreshToken);

            ///////////////////////////////////////////////////////////////////
            // Assert
            //

            var actionResult = refreshResult.Result;

            Assert.Equal("Microsoft.AspNetCore.Mvc.OkObjectResult", actionResult.GetType().ToString());
        }
예제 #4
0
        public void JwtController_CanIssueTokens()
        {
            ///////////////////////////////////////////////////////////////////
            // Arrange
            //

            //   Options
            string secret = "A_KEY_MUST_BE_16_CHARS+";
            SymmetricSecurityKey signingKey         = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret.PadRight(16)));
            SigningCredentials   signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

            var jwtIssuerOptions = new JwtIssuerOptions
            {
                Issuer          = "TokenIssuer", Audience = "TokenAudience",
                AccessValidFor  = TimeSpan.FromSeconds(10), RefreshValidFor = TimeSpan.FromSeconds(100),
                AccessClockSkew = 0, RefreshClockSkew = 0,
                Subject         = "Alice", SigningCredentials = signingCredentials
            };

            var mockOptions = new Mock <IOptions <JwtIssuerOptions> >();

            mockOptions.Setup(mo => mo.Value).Returns(jwtIssuerOptions);

            //   UserManager
            var fakeUserManager = new FakeUserManager();

            //   TokenStore
            var tokenStore = new ExampleTokenStore();

            //   Configuration
            var mockConfiguration = new Mock <IConfiguration>();

            mockConfiguration.SetupGet(m => m[Constants.SECRET_ENV_VAR]).Returns(secret);

            //   Logger
            var mockLogger = new Mock <ILogger <JwtController> >();

            JwtController controller = new JwtController(mockOptions.Object, fakeUserManager, tokenStore, mockConfiguration.Object, mockLogger.Object);

            // Credentials
            LoginCredentials creds = new LoginCredentials {
                UserName = "******", Password = "******"
            };



            ///////////////////////////////////////////////////////////////////
            // Act
            //

            var result = controller.Issue(creds);


            ///////////////////////////////////////////////////////////////////
            // Assert
            //

            // Task should finish
            var resultStatus = result.Status;

            // Result should be 200 OK
            var actionResult = result.Result;

            checkActionResult(actionResult, jwtIssuerOptions, signingKey);
        }