public void ExpiredRefreshToken()
        {
            TestTokenHandleManager handleManager =
                new TestTokenHandleManager("abc", "codeclient", "https://validredirect", expired: true);

            var validator = new TokenRequestValidator(handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.RefreshToken,
                Refresh_Token = "abc"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidGrant, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void MissingClientId()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.Password,
                UserName = "******",
                Password = "******",
                Scope = "read"
            };

            try
            {
                var client = Principal.Create("Test",
                                new Claim("password", "secret"));

                var result = validator.Validate(app, request, client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidClient, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void ValidSingleScope()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.ClientCredentials,
                Scope = "read"
            };

            var result = validator.Validate(app, request, _client);
        }
        public void ValidRequest()
        {
            var validator = new TokenRequestValidator(_handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.RefreshToken,
                Refresh_Token = "abc"
            };

            var result = validator.Validate(app, request, _client);
        }
        public void ValidCodeGrant()
        {
            var validator = new TokenRequestValidator(new TestTokenHandleManager("codeclient", "https://todo"));
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
                Code = "abc",
                Redirect_Uri = "https://todo"
            };

            var result = validator.Validate(app, request, _codeClient);
        }
        public void ValidSingleScope()
        {
            var validator = new TokenRequestValidator(_clientManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = "assertion",
                Assertion = "assertion",
                Scope = "read"
            };

            var result = validator.Validate(app, request, _client);
        }
        public void ValidSingleScope()
        {
            var validator = new TokenRequestValidator(_handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
                Code = "abc",
                Redirect_Uri = "https://validredirect"
            };

            var result = validator.Validate(app, request, _client);
        }
        public void ValidSingleScope()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.Password,
                UserName = "******",
                Password = "******",
                Scope = "read"
            };

            var result = validator.Validate(app, request, _client);
        }
        public HttpResponseMessage Post(string appName, TokenRequest request)
        {
            Tracing.Start("OAuth2 Token Endpoint");

            // make sure application is registered
            var application = _config.FindApplication(appName);
            if (application == null)
            {
                Tracing.Error("Application not found: " + appName);
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Not found");
            }

            // validate token request
            ValidatedRequest validatedRequest;
            try
            {
                validatedRequest = new TokenRequestValidator(_handleManager).Validate(application, request, ClaimsPrincipal.Current);
            }
            catch (TokenRequestValidationException ex)
            {
                Tracing.Error("Aborting OAuth2 token request");
                return Request.CreateOAuthErrorResponse(ex.OAuthError);
            }

            // switch over the grant type
            if (validatedRequest.GrantType.Equals(OAuthConstants.GrantTypes.Password))
            {
                return ProcessResourceOwnerCredentialRequest(validatedRequest);
            }
            else if (validatedRequest.GrantType.Equals(OAuthConstants.GrantTypes.AuthorizationCode))
            {
                return ProcessAuthorizationCodeRequest(validatedRequest);
            }
            else if (string.Equals(validatedRequest.GrantType, OAuthConstants.GrantTypes.RefreshToken))
            {
                return ProcessRefreshTokenRequest(validatedRequest);
            }
            else if (string.Equals(validatedRequest.GrantType, OAuthConstants.GrantTypes.ClientCredentials))
            {
                return ProcessClientCredentialsRequest(validatedRequest);
            }

            Tracing.Error("invalid grant type: " + request.Grant_Type);
            return Request.CreateOAuthErrorResponse(OAuthConstants.Errors.UnsupportedGrantType);
        }
        public void MissingCode()
        {
            var validator = new TokenRequestValidator(_handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.RefreshToken,
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidGrant, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void MissingScope()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.ClientCredentials,
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidScope, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void MissingScope()
        {
            var validator = new TokenRequestValidator(_clientManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.Password,
                UserName = "******",
                Password = "******",
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidScope, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void NonMatchingRedirectUri()
        {
            var validator = new TokenRequestValidator(_handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
                Code = "abc",
                Redirect_Uri = "https://invalidredirect"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidRequest, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void UnknownScope()
        {
            var validator = new TokenRequestValidator(_clientManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = "assertion",
                Assertion = "assertion",
                Scope = "unknown"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidScope, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void UnauthorizedClientCredentialGrant()
        {
            var validator = new TokenRequestValidator(_handleManager, _clientManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.ClientCredentials,
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.UnauthorizedClient, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void InvalidCodeToClientBinding()
        {
            var handleManager =
                new TestTokenHandleManager("abc", "someotherclient", "https://validredirect");

            var validator = new TokenRequestValidator(handleManager, _clientManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
                Code = "abc",
                Redirect_Uri = "https://validredirect"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidGrant, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void UnauthorizedScopeSingle()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.Password,
                UserName = "******",
                Password = "******",
                Scope = "delete"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidScope, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        private void ValidateRefreshTokenGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (_handleManager == null)
            {
                throw new ArgumentNullException("HandleManager");
            }

            if (!validatedRequest.Client.AllowRefreshToken)
            {
                throw new TokenRequestValidationException(
                    "Refresh tokens not allowed for client",
                    OAuthConstants.Errors.UnsupportedGrantType);
            }

            // check for refresh token
            if (string.IsNullOrWhiteSpace(request.Refresh_Token))
            {
                throw new TokenRequestValidationException(
                    "Missing refresh token",
                    OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.RefreshToken = request.Refresh_Token;
            Tracing.Information("Refresh token: " + validatedRequest.RefreshToken);

            // check for refresh token in datastore
            var handle = _handleManager.Get(validatedRequest.RefreshToken);
            if (handle == null)
            {
                throw new TokenRequestValidationException(
                    "Refresh token not found: " + validatedRequest.RefreshToken,
                    OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.TokenHandle = handle;
            Tracing.Information("Token handle found: " + handle.HandleId);

            // check the client binding
            if (handle.Client.ClientId != validatedRequest.Client.ClientId)
            {
                throw new TokenRequestValidationException(
                    string.Format("Client {0} is trying to refresh token from {1}.", validatedRequest.Client.ClientId, handle.Client.ClientId),
                    OAuthConstants.Errors.InvalidGrant);
            }
        }
        public void Refresh_Token_Create_New()
        {
            Claim[] claims = { new Claim("client_id", "MobileAppShop"), new Claim("secret", "12345678") };
            ClaimsPrincipal claimsPrinciple = Principal.Create("Test", claims);

            Thread.CurrentPrincipal = claimsPrinciple;

            TokenRequest tokenRequest = new TokenRequest()
            {
                Grant_Type = "refresh_token",
                Refresh_Token = "MyFavouriteRefrehToken1234"
            };

            var response = _TokenController.Post("Test Application 1", tokenRequest);
            TokenResponse tokenResponse;
            response.TryGetContentValue<TokenResponse>(out tokenResponse);

            Assert.IsTrue(response.IsSuccessStatusCode == true);
            Assert.IsFalse(string.IsNullOrEmpty(tokenResponse.AccessToken));
        }
        public void UnknownGrantType()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = "unknown"
            };

            try
            {
                var result = validator.Validate(app, request, null);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.UnsupportedGrantType, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public ValidatedRequest Validate(Application application, TokenRequest request, ClaimsPrincipal clientPrincipal)
        {
            var validatedRequest = new ValidatedRequest();

            // validate request model binding
            if (request == null)
            {
                throw new TokenRequestValidationException(
                          "Invalid request parameters.",
                          OAuthConstants.Errors.InvalidRequest);
            }

            validatedRequest.Application = application;
            Tracing.InformationFormat("OAuth2 application: {0} ({1})",
                                      validatedRequest.Application.Name,
                                      validatedRequest.Application.Namespace);

            // grant type is required
            if (string.IsNullOrWhiteSpace(request.Grant_Type))
            {
                throw new TokenRequestValidationException(
                          "Missing grant_type",
                          OAuthConstants.Errors.UnsupportedGrantType);
            }

            // check supported grant types
            if (request.Grant_Type == OAuthConstants.GrantTypes.AuthorizationCode ||
                request.Grant_Type == OAuthConstants.GrantTypes.ClientCredentials ||
                request.Grant_Type == OAuthConstants.GrantTypes.RefreshToken ||
                request.Grant_Type == OAuthConstants.GrantTypes.Password)
            {
                validatedRequest.GrantType = request.Grant_Type;
                Tracing.Information("Grant type: " + validatedRequest.GrantType);
            }
            else if (!string.IsNullOrWhiteSpace(request.Assertion))
            {
                validatedRequest.GrantType     = OAuthConstants.GrantTypes.Assertion;
                validatedRequest.AssertionType = request.Grant_Type;
                validatedRequest.Assertion     = request.Assertion;

                Tracing.Information("Grant type: " + validatedRequest.GrantType);
            }
            else
            {
                throw new TokenRequestValidationException(
                          "Invalid grant_type: " + request.Grant_Type,
                          OAuthConstants.Errors.UnsupportedGrantType);
            }

            // validate client credentials
            var client = ValidateClient(clientPrincipal, validatedRequest.Application);

            if (client == null)
            {
                throw new TokenRequestValidationException(
                          "Invalid client: " + ClaimsPrincipal.Current.Identity.Name,
                          OAuthConstants.Errors.InvalidClient);
            }

            validatedRequest.Client = client;
            Tracing.InformationFormat("Client: {0} ({1})",
                                      validatedRequest.Client.Name,
                                      validatedRequest.Client.ClientId);

            switch (validatedRequest.GrantType)
            {
            case OAuthConstants.GrantTypes.AuthorizationCode:
                ValidateCodeGrant(validatedRequest, request);
                break;

            case OAuthConstants.GrantTypes.Password:
                ValidatePasswordGrant(validatedRequest, request);
                break;

            case OAuthConstants.GrantTypes.RefreshToken:
                ValidateRefreshTokenGrant(validatedRequest, request);
                break;

            case OAuthConstants.GrantTypes.ClientCredentials:
                ValidateClientCredentialsGrant(validatedRequest, request);
                break;

            case OAuthConstants.GrantTypes.Assertion:
                ValidateAssertionGrant(validatedRequest, request);
                break;

            default:
                throw new TokenRequestValidationException(
                          "Invalid grant_type: " + request.Grant_Type,
                          OAuthConstants.Errors.UnsupportedGrantType);
            }

            Tracing.Information("Token request validation successful.");
            return(validatedRequest);
        }
        private static void ValidateScopes(ValidatedRequest validatedRequest, TokenRequest request)
        {
            // validate scope
            if (string.IsNullOrWhiteSpace(request.Scope))
            {
                throw new TokenRequestValidationException(
                    "Missing scope",
                    OAuthConstants.Errors.InvalidScope);
            }

            // make sure client is allowed to request all scope
            var requestedScopes = request.Scope.Split(' ').ToList();
            List<Scope> resultingScopes;

            if (validatedRequest.Application.Scopes.TryValidateScopes(validatedRequest.Client.ClientId, requestedScopes, out resultingScopes))
            {
                validatedRequest.Scopes = resultingScopes;
                Tracing.InformationFormat("Requested scopes: {0}", request.Scope);
            }
            else
            {
                throw new TokenRequestValidationException(
                    "Invalid scope",
                    OAuthConstants.Errors.InvalidScope);
            }
        }
        private void ValidateCodeGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (_handleManager == null)
            {
                throw new ArgumentNullException("HandleManager");
            }

            if (validatedRequest.Client.Flow != OAuthFlow.Code)
            {
                throw new TokenRequestValidationException(
                          "Code flow not allowed for client",
                          OAuthConstants.Errors.UnauthorizedClient);
            }

            // code needs to be present
            if (string.IsNullOrWhiteSpace(request.Code))
            {
                throw new TokenRequestValidationException(
                          "Missing authorization code",
                          OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.AuthorizationCode = request.Code;
            Tracing.Information("Authorization code: " + validatedRequest.AuthorizationCode);

            // check for authorization code in datastore
            var handle = _handleManager.Get(validatedRequest.AuthorizationCode);

            if (handle == null)
            {
                throw new TokenRequestValidationException(
                          "Authorization code not found: " + validatedRequest.AuthorizationCode,
                          OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.StoredGrant = handle;
            Tracing.Information("Token handle found: " + handle.GrantId);

            // check the client binding
            if (handle.Client.ClientId != validatedRequest.Client.ClientId)
            {
                throw new TokenRequestValidationException(
                          string.Format("Client {0} is trying to request token using an authorization code from {1}.", validatedRequest.Client.ClientId, handle.Client.ClientId),
                          OAuthConstants.Errors.InvalidGrant);
            }

            // redirect URI is required
            if (string.IsNullOrWhiteSpace(request.Redirect_Uri))
            {
                throw new TokenRequestValidationException(
                          string.Format("Redirect URI is missing"),
                          OAuthConstants.Errors.InvalidRequest);
            }

            // check if redirect URI from authorize and token request match
            if (!handle.RedirectUri.Equals(request.Redirect_Uri))
            {
                throw new TokenRequestValidationException(
                          string.Format("Redirect URI in token request ({0}), does not match redirect URI from authorize request ({1})", validatedRequest.RedirectUri, handle.RedirectUri),
                          OAuthConstants.Errors.InvalidRequest);
            }
        }
        private void ValidateCodeGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (_handleManager == null)
            {
                throw new ArgumentNullException("HandleManager");
            }

            if (validatedRequest.Client.Flow != OAuthFlow.Code)
            {
                throw new TokenRequestValidationException(
                    "Code flow not allowed for client",
                    OAuthConstants.Errors.UnsupportedGrantType);
            }

            // code needs to be present
            if (string.IsNullOrWhiteSpace(request.Code))
            {
                throw new TokenRequestValidationException(
                    "Missing authorization code",
                    OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.AuthorizationCode = request.Code;
            Tracing.Information("Authorization code: " + validatedRequest.AuthorizationCode);
            
            // check for authorization code in datastore
            var handle = _handleManager.Get(validatedRequest.AuthorizationCode);
            if (handle == null)
            {
                throw new TokenRequestValidationException(
                    "Authorization code not found: " + validatedRequest.AuthorizationCode,
                    OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.TokenHandle = handle;
            Tracing.Information("Token handle found: " + handle.HandleId);

            // check the client binding
            if (handle.Client.ClientId != validatedRequest.Client.ClientId)
            {
                throw new TokenRequestValidationException(
                    string.Format("Client {0} is trying to request token using an authorization code from {1}.", validatedRequest.Client.ClientId, handle.Client.ClientId),
                    OAuthConstants.Errors.InvalidGrant);
            }

            // redirect URI is required
            if (string.IsNullOrWhiteSpace(request.Redirect_Uri))
            {
                throw new TokenRequestValidationException(
                    string.Format("Redirect URI is missing"),
                    OAuthConstants.Errors.InvalidRequest);
            }

            // check if redirect URI from authorize and token request match
            if (!handle.RedirectUri.Equals(request.Redirect_Uri))
            {
                throw new TokenRequestValidationException(
                    string.Format("Redirect URI in token request ({0}), does not match redirect URI from authorize request ({1})", validatedRequest.RedirectUri, handle.RedirectUri),
                    OAuthConstants.Errors.InvalidRequest);
            }
        }
        public ValidatedRequest Validate(Application application, TokenRequest request, ClaimsPrincipal clientPrincipal)
        {
            var validatedRequest = new ValidatedRequest();

            // validate request model binding
            if (request == null)
            {
                throw new TokenRequestValidationException(
                    "Invalid request parameters.",
                    OAuthConstants.Errors.InvalidRequest);
            }

            validatedRequest.Application = application;
            Tracing.InformationFormat("OAuth2 application: {0} ({1})",
                validatedRequest.Application.Name,
                validatedRequest.Application.Namespace);

            // grant type is required
            if (string.IsNullOrWhiteSpace(request.Grant_Type))
            {
                throw new TokenRequestValidationException(
                    "Missing grant_type",
                    OAuthConstants.Errors.UnsupportedGrantType);
            }

            validatedRequest.GrantType = request.Grant_Type;
            Tracing.Information("Grant type: " + validatedRequest.GrantType);

            // validate client credentials
            var client = ValidateClient(clientPrincipal, validatedRequest.Application);
            if (client == null)
            {
                throw new TokenRequestValidationException(
                    "Invalid client: " + ClaimsPrincipal.Current.Identity.Name,
                    OAuthConstants.Errors.InvalidClient);
            }

            validatedRequest.Client = client;
            Tracing.InformationFormat("Client: {0} ({1})",
                validatedRequest.Client.Name,
                validatedRequest.Client.ClientId);

            switch (request.Grant_Type)
            {
                case OAuthConstants.GrantTypes.AuthorizationCode:
                    ValidateCodeGrant(validatedRequest, request);
                    break;
                case OAuthConstants.GrantTypes.Password:
                    ValidatePasswordGrant(validatedRequest, request);
                    break;
                case OAuthConstants.GrantTypes.RefreshToken:
                    ValidateRefreshTokenGrant(validatedRequest, request);
                    break;
                case OAuthConstants.GrantTypes.ClientCredentials:
                    ValidateClientCredentialsGrant(validatedRequest, request);
                    break;
                default:
                    throw new TokenRequestValidationException(
                        "Invalid grant_type: " + request.Grant_Type,
                        OAuthConstants.Errors.UnsupportedGrantType);
            }

            Tracing.Information("Token request validation successful.");
            return validatedRequest;
        }
        private void ValidateClientCredentialsGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (validatedRequest.Client.Flow != OAuthFlow.Client)
            {
                throw new TokenRequestValidationException(
                    "Client flow not allowed for client",
                    OAuthConstants.Errors.UnsupportedGrantType);
            }

            ValidateScopes(validatedRequest, request);
        }
        private void ValidateClientCredentialsGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (validatedRequest.Client.Flow != OAuthFlow.Client)
            {
                throw new TokenRequestValidationException(
                          "Client flow not allowed for client",
                          OAuthConstants.Errors.UnauthorizedClient);
            }

            ValidateScopes(validatedRequest, request);
        }
        public void DisabledClient()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.ClientCredentials
            };

            try
            {
                var client = Principal.Create("Test",
                new Claim("client_id", "disabledclient"),
                new Claim("secret", "secret"));

                var result = validator.Validate(app, request, client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidClient, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void AnonymousCodeGrant()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
                Code = "abc",
                Redirect_Uri = "https://validredirect"
            };

            try
            {
                var result = validator.Validate(app, request, Principal.Anonymous);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidClient, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        private void ValidatePasswordGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (validatedRequest.Client.Flow != OAuthFlow.ResourceOwner)
            {
                throw new TokenRequestValidationException(
                    "Resource owner password flow not allowed for client",
                    OAuthConstants.Errors.UnsupportedGrantType);
            }

            ValidateScopes(validatedRequest, request);

            // extract username and password
            if (string.IsNullOrWhiteSpace(request.UserName) || string.IsNullOrWhiteSpace(request.Password))
            {
                throw new TokenRequestValidationException(
                    "Missing Username or password.",
                    OAuthConstants.Errors.InvalidGrant);
            }
            else
            {
                validatedRequest.UserName = request.UserName;
                validatedRequest.Password = request.Password;

                Tracing.Information("Resource owner: " + request.UserName);
            }
        }
        public void MissingResourceOwnerPassword()
        {
            var validator = new TokenRequestValidator();
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.Password,
                UserName = "******",
                Scope = "read"
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.InvalidGrant, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        public void UnauthorizedCodeGrant()
        {
            TestTokenHandleManager handleManager =
                new TestTokenHandleManager("abc", "codeclient", "https://validredirect");
            
            var validator = new TokenRequestValidator(handleManager);
            var app = _testConfig.FindApplication("test");
            var request = new TokenRequest
            {
                Grant_Type = OAuthConstants.GrantTypes.AuthorizationCode,
            };

            try
            {
                var result = validator.Validate(app, request, _client);
            }
            catch (TokenRequestValidationException ex)
            {
                Assert.AreEqual(OAuthConstants.Errors.UnauthorizedClient, ex.OAuthError);
                return;
            }

            Assert.Fail("No exception thrown.");
        }
        private void ValidateRefreshTokenGrant(ValidatedRequest validatedRequest, TokenRequest request)
        {
            if (_handleManager == null)
            {
                throw new ArgumentNullException("HandleManager");
            }

            if (!validatedRequest.Client.AllowRefreshToken)
            {
                throw new TokenRequestValidationException(
                          "Refresh tokens not allowed for client",
                          OAuthConstants.Errors.UnauthorizedClient);
            }

            // check for refresh token
            if (string.IsNullOrWhiteSpace(request.Refresh_Token))
            {
                throw new TokenRequestValidationException(
                          "Missing refresh token",
                          OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.RefreshToken = request.Refresh_Token;
            Tracing.Information("Refresh token: " + validatedRequest.RefreshToken);

            // check for refresh token in datastore
            var handle = _handleManager.Get(validatedRequest.RefreshToken);

            if (handle == null)
            {
                throw new TokenRequestValidationException(
                          "Refresh token not found: " + validatedRequest.RefreshToken,
                          OAuthConstants.Errors.InvalidGrant);
            }

            validatedRequest.StoredGrant = handle;
            Tracing.Information("Token handle found: " + handle.GrantId);

            // make sure the refresh token has an expiration time
            if (validatedRequest.StoredGrant.Expiration == null)
            {
                throw new TokenRequestValidationException(
                          "No expiration time set for refresh token. That's not allowed.",
                          OAuthConstants.Errors.InvalidGrant);
            }

            // make sure refresh token has not expired
            if (DateTime.UtcNow > validatedRequest.StoredGrant.Expiration)
            {
                throw new TokenRequestValidationException(
                          "Refresh token expired.",
                          OAuthConstants.Errors.InvalidGrant);
            }

            // check the client binding
            if (handle.Client.ClientId != validatedRequest.Client.ClientId)
            {
                throw new TokenRequestValidationException(
                          string.Format("Client {0} is trying to refresh token from {1}.", validatedRequest.Client.ClientId, handle.Client.ClientId),
                          OAuthConstants.Errors.InvalidGrant);
            }
        }
        public void Create_Token()
        {
            Claim[] claims = { new Claim("client_id", "MobileAppShop"), new Claim("secret", "12345678") };
            ClaimsPrincipal claimsPrinciple = Principal.Create("Test", claims);

            Thread.CurrentPrincipal = claimsPrinciple;

            TokenRequest tokenRequest = new TokenRequest()
            {
                Grant_Type = "password",
                UserName = "******",
                Password = "******",
                Scope = "read",
            };

            var response = _TokenController.Post("Test Application 1", tokenRequest);
            TokenResponse tokenResponse;
            response.TryGetContentValue<TokenResponse>(out tokenResponse);

            Assert.IsTrue(response.IsSuccessStatusCode == true);
            Assert.IsFalse(string.IsNullOrEmpty(tokenResponse.AccessToken));
        }