Beispiel #1
0
        public async Task Code_Request_PKCE_Missing_CodeVerifier(string clientId)
        {
            var client = await _clients.FindClientByIdAsync(clientId);

            var store   = new InMemoryAuthorizationCodeStore();
            var options = new IdentityServerOptions();

            var code = new AuthorizationCode
            {
                Client              = client,
                Subject             = IdentityServerPrincipal.Create("123", "bob"),
                RedirectUri         = "https://server/cb",
                CodeChallenge       = "x".Repeat(options.InputLengthRestrictions.CodeChallengeMinLength + 1),
                CodeChallengeMethod = Constants.CodeChallengeMethods.Plain,
                RequestedScopes     = new List <Scope>
                {
                    new Scope
                    {
                        Name = "openid"
                    }
                }
            };

            await store.StoreAsync("valid", code);

            var validator = Factory.CreateTokenRequestValidator(
                authorizationCodeStore: store);

            var parameters = new NameValueCollection();

            parameters.Add(Constants.TokenRequest.GrantType, Constants.GrantTypes.AuthorizationCode);
            parameters.Add(Constants.TokenRequest.Code, "valid");
            parameters.Add(Constants.TokenRequest.RedirectUri, "https://server/cb");

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(Constants.TokenErrors.InvalidGrant);
        }
        public async Task Authenticated_User_with_restricted_current_Idp_must_SignIn()
        {
            var users     = new Mock <IUserService>();
            var generator = new AuthorizeInteractionResponseGenerator(options, null, users.Object, new DefaultLocalizationService());

            var request = new ValidatedAuthorizeRequest
            {
                ClientId = "foo",
                Subject  = IdentityServerPrincipal.Create("123", "dom"),
                Client   = new Client
                {
                    IdentityProviderRestrictions = new List <string>
                    {
                        "some_idp"
                    }
                }
            };

            var result = await generator.ProcessClientLoginAsync(request);

            result.IsLogin.Should().BeTrue();
        }
Beispiel #3
0
        public DefaultClaimsServiceTests()
        {
            _validatedRequest = new ValidatedRequest
            {
            };

            _client = new Client
            {
                ClientId = "client",
                Claims   = { new Claim("some_claim", "some_claim_value") }
            };

            _user = IdentityServerPrincipal.Create("bob", "bob", new Claim[] {
                new Claim("foo", "foo1"),
                new Claim("foo", "foo2"),
                new Claim("bar", "bar1"),
                new Claim("bar", "bar2"),
                new Claim(JwtClaimTypes.AuthenticationContextClassReference, "acr1")
            });

            _subject = new DefaultClaimsService(_mockMockProfileService, TestLogger.Create <DefaultClaimsService>());
        }
        public async Task valid_pkce_token_request_with_plain_method_should_succeed_hybrid()
        {
            var client = await _clients.FindEnabledClientByIdAsync("hybridclient.pkce");

            var grants   = Factory.CreateGrantService();
            var verifier = "x".Repeat(lengths.CodeVerifierMinLength);

            var code = new AuthorizationCode
            {
                Subject             = IdentityServerPrincipal.Create("123", "bob"),
                ClientId            = client.ClientId,
                Lifetime            = client.AuthorizationCodeLifetime,
                RedirectUri         = "https://server/cb",
                CodeChallenge       = verifier.Sha256(),
                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Plain,

                RequestedScopes = new List <string>
                {
                    "openid"
                }
            };

            await grants.StoreAuthorizationCodeAsync("valid", code);

            var validator = Factory.CreateTokenRequestValidator(
                grants: grants);

            var parameters = new NameValueCollection();

            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);
            parameters.Add(OidcConstants.TokenRequest.Code, "valid");
            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier);
            parameters.Add(OidcConstants.TokenRequest.RedirectUri, "https://server/cb");

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeFalse();
        }
Beispiel #5
0
        public async Task Authenticated_User_with_local_Idp_must_SignIn_when_client_options_does_not_allow_local_logins()
        {
            options.AuthenticationOptions.EnableLocalLogin = true;

            var users     = new Mock <IUserService>();
            var generator = new AuthorizeInteractionResponseGenerator(options, null, users.Object, new DefaultLocalizationService());

            var request = new ValidatedAuthorizeRequest
            {
                ClientId = "foo",
                Subject  = IdentityServerPrincipal.Create("123", "dom"),
                Client   = new Client
                {
                    ClientId         = "foo",
                    EnableLocalLogin = false
                }
            };

            var principal = IdentityServerPrincipal.Create("123", "dom");
            var result    = await generator.ProcessClientLoginAsync(request);

            result.IsLogin.Should().BeTrue();
        }
Beispiel #6
0
        public async Task valid_id_token_hint_but_no_post_logout_redirect_uri_should_not_use_any_of_multiple_registered_post_logout_redirect_uri()
        {
            await _mockPipeline.LoginAsync(IdentityServerPrincipal.Create("bob", "Bob Loblaw"));

            _mockPipeline.BrowserClient.AllowAutoRedirect = false;
            var url = _mockPipeline.CreateAuthorizeUrl(
                clientId: "client2",
                responseType: "id_token",
                scope: "openid",
                redirectUri: "https://client2/callback",
                state: "123_state",
                nonce: "123_nonce");
            var response = await _mockPipeline.BrowserClient.GetAsync(url);

            var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
            var id_token      = authorization.IdentityToken;

            _mockPipeline.BrowserClient.AllowAutoRedirect = true;
            response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
                                                                  "?id_token_hint=" + id_token);

            _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().BeNull();
        }
        public async Task signin_response_should_allow_successful_authorization_response()
        {
            _mockPipeline.Subject = IdentityServerPrincipal.Create("bob", "Bob Loblaw");
            _mockPipeline.BrowserClient.StopRedirectingAfter = 2;

            var url = _mockPipeline.CreateAuthorizeUrl(
                clientId: "client1",
                responseType: "id_token",
                scope: "openid",
                redirectUri: "https://client1/callback",
                state: "123_state",
                nonce: "123_nonce");
            var response = await _mockPipeline.BrowserClient.GetAsync(url);

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith("https://client1/callback");

            var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());

            authorization.IsError.Should().BeFalse();
            authorization.IdentityToken.Should().NotBeNull();
            authorization.State.Should().Be("123_state");
        }
        public Task <ClaimsPrincipal> ValidateAsync(ValidatedTokenRequest request)
        {
            if (request.GrantType != "custom")
            {
                return(Task.FromResult <ClaimsPrincipal>(null));
            }

            var assertion = request.Raw.Get("assertion");

            if (string.IsNullOrWhiteSpace(assertion))
            {
                return(Task.FromResult <ClaimsPrincipal>(null));
            }

            // validate assertion and return principal
            var principal = IdentityServerPrincipal.Create(
                "bob",
                "bob",
                "custom_grant",
                "idsrv");

            return(Task.FromResult(principal));
        }
Beispiel #9
0
        public async Task valid_signout_callback_should_render_iframes_for_all_clients()
        {
            await _mockPipeline.LoginAsync(IdentityServerPrincipal.Create("bob", "Bob Loblaw"));

            var sid = _mockPipeline.GetSessionCookie().Value;

            _mockPipeline.BrowserClient.AllowAutoRedirect = false;
            var url = _mockPipeline.CreateAuthorizeUrl(
                clientId: "client1",
                responseType: "id_token",
                scope: "openid",
                redirectUri: "https://client1/callback",
                state: "123_state",
                nonce: "123_nonce");
            var response = await _mockPipeline.BrowserClient.GetAsync(url);

            var url2 = _mockPipeline.CreateAuthorizeUrl(
                clientId: "client2",
                responseType: "id_token",
                scope: "openid",
                redirectUri: "https://client2/callback",
                state: "123_state",
                nonce: "123_nonce");
            var response2 = await _mockPipeline.BrowserClient.GetAsync(url2);

            _mockPipeline.BrowserClient.AllowAutoRedirect = true;
            response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);

            var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;

            response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);

            var html = await response.Content.ReadAsStringAsync();

            html.Should().Contain("https://client1/signout?sid=" + sid + "&iss=" + UrlEncoder.Default.Encode("https://server"));
            html.Should().Contain("https://client2/signout?sid=" + sid + "&iss=" + UrlEncoder.Default.Encode("https://server"));
        }
        public async Task Code_Request_with_disabled_User()
        {
            var client = await _clients.FindClientByIdAsync("codeclient");

            var store = new InMemoryAuthorizationCodeStore();

            var code = new AuthorizationCode
            {
                Client          = client,
                Subject         = IdentityServerPrincipal.Create("123", "bob"),
                RedirectUri     = "https://server/cb",
                RequestedScopes = new List <Scope>
                {
                    new Scope
                    {
                        Name = "openid"
                    }
                }
            };

            await store.StoreAsync("valid", code);

            var validator = Factory.CreateTokenRequestValidator(
                authorizationCodeStore: store,
                profile: new TestProfileService(shouldBeActive: false));

            var parameters = new NameValueCollection();

            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);
            parameters.Add(OidcConstants.TokenRequest.Code, "valid");
            parameters.Add(OidcConstants.TokenRequest.RedirectUri, "https://server/cb");

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);
        }
        public async Task token_request_with_missing_code_challenge_should_fail(string clientId)
        {
            var client = await _clients.FindEnabledClientByIdAsync(clientId);

            var grants = Factory.CreateAuthorizationCodeStore();

            var code = new AuthorizationCode
            {
                CreationTime = DateTime.UtcNow,
                Subject      = IdentityServerPrincipal.Create("123", "bob"),
                ClientId     = client.ClientId,
                Lifetime     = client.AuthorizationCodeLifetime,
                RedirectUri  = "https://server/cb",

                RequestedScopes = new List <string>
                {
                    "openid"
                }
            };

            var handle = await grants.StoreAuthorizationCodeAsync(code);

            var validator = Factory.CreateTokenRequestValidator(
                authorizationCodeStore: grants);

            var parameters = new NameValueCollection();

            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);
            parameters.Add(OidcConstants.TokenRequest.Code, handle);
            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, "x".Repeat(lengths.CodeVerifierMinLength));
            parameters.Add(OidcConstants.TokenRequest.RedirectUri, "https://server/cb");

            var result = await validator.ValidateRequestAsync(parameters, client);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);
        }
        public async Task Code_Request_with_disabled_User()
        {
            var client = await _clients.FindEnabledClientByIdAsync("codeclient");

            var store = Factory.CreateAuthorizationCodeStore();

            var code = new AuthorizationCode
            {
                CreationTime    = DateTime.UtcNow,
                ClientId        = client.ClientId,
                Lifetime        = client.AuthorizationCodeLifetime,
                Subject         = IdentityServerPrincipal.Create("123", "bob"),
                RedirectUri     = "https://server/cb",
                RequestedScopes = new List <string>
                {
                    "openid"
                }
            };

            var handle = await store.StoreAuthorizationCodeAsync(code);

            var validator = Factory.CreateTokenRequestValidator(
                authorizationCodeStore: store,
                profile: new TestProfileService(shouldBeActive: false));

            var parameters = new NameValueCollection();

            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);
            parameters.Add(OidcConstants.TokenRequest.Code, handle);
            parameters.Add(OidcConstants.TokenRequest.RedirectUri, "https://server/cb");

            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());

            result.IsError.Should().BeTrue();
            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);
        }
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _subject.StoreUserConsentAsync(new Consent
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new[] { "foo1", "foo2" }
            });

            await _subject.StoreUserConsentAsync(new Consent
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new[] { "foo3" }
            });

            await _subject.StoreUserConsentAsync(new Consent
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new[] { "foo3" }
            });

            await _subject.StoreReferenceTokenAsync("key1", new Token
            {
                ClientId     = "client1",
                Audience     = "aud",
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2")
                }
            });

            await _subject.StoreReferenceTokenAsync("key2", new Token
            {
                ClientId     = "client2",
                Audience     = "aud",
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3")
                }
            });

            await _subject.StoreReferenceTokenAsync("key3", new Token
            {
                ClientId     = "client1",
                Audience     = "aud",
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3")
                }
            });

            await _subject.StoreRefreshTokenAsync("key4", new RefreshToken
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audience     = "aud",
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            await _subject.StoreRefreshTokenAsync("key5", new RefreshToken
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audience     = "aud",
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            await _subject.StoreRefreshTokenAsync("key6", new RefreshToken
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audience     = "aud",
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            await _subject.StoreAuthorizationCodeAsync("key7", new AuthorizationCode
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new[] { "quux1", "quux2" }
            });

            await _subject.StoreAuthorizationCodeAsync("key8", new AuthorizationCode
            {
                ClientId        = "client2",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new[] { "quux3" }
            });

            await _subject.StoreAuthorizationCodeAsync("key9", new AuthorizationCode
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = IdentityServerPrincipal.Create("456", "alice"),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _subject.GetReferenceTokenAsync("key1")).Should().BeNull();
            (await _subject.GetReferenceTokenAsync("key2")).Should().NotBeNull();
            (await _subject.GetReferenceTokenAsync("key3")).Should().NotBeNull();
            (await _subject.GetRefreshTokenAsync("key4")).Should().BeNull();
            (await _subject.GetRefreshTokenAsync("key5")).Should().NotBeNull();
            (await _subject.GetRefreshTokenAsync("key6")).Should().NotBeNull();
            (await _subject.GetAuthorizationCodeAsync("key7")).Should().BeNull();
            (await _subject.GetAuthorizationCodeAsync("key8")).Should().NotBeNull();
            (await _subject.GetAuthorizationCodeAsync("key9")).Should().NotBeNull();
        }
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2"),
                },
            });

            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3"),
                },
            });

            var handle3 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3"),
                },
            });

            var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            var handle5 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            var handle6 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            var handle7 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            var handle8 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = IdentityServerPrincipal.Create("456", "alice"),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _referenceTokens.GetReferenceTokenAsync(handle1)).Should().BeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle2)).Should().NotBeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle3)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().BeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle5)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle6)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle7)).Should().BeNull();
            (await _codes.GetAuthorizationCodeAsync(handle8)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle9)).Should().NotBeNull();
        }
Beispiel #15
0
        private async Task <ValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                RaiseRefreshTokenRefreshFailureEvent(null, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                var error = "Refresh token is invalid";
                LogWarn(error);
                RaiseRefreshTokenRefreshFailureEvent(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime))
            {
                var error = "Refresh token has expired";
                LogWarn(error);
                RaiseRefreshTokenRefreshFailureEvent(refreshTokenHandle, error);

                await _refreshTokens.RemoveAsync(refreshTokenHandle);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId));
                RaiseRefreshTokenRefreshFailureEvent(refreshTokenHandle, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ScopeRestrictions != null && _validatedRequest.Client.ScopeRestrictions.Count != 0)
            {
                if (!_validatedRequest.Client.ScopeRestrictions.Contains(Constants.StandardScopes.OfflineAccess))
                {
                    var error = "Client does not have access to offline_access scope anymore";
                    LogError(error);
                    RaiseRefreshTokenRefreshFailureEvent(refreshTokenHandle, error);

                    return(Invalid(Constants.TokenErrors.InvalidGrant));
                }
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims);

            if (await _users.IsActiveAsync(principal) == false)
            {
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                LogError(error);
                RaiseRefreshTokenRefreshFailureEvent(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            Logger.Info("Validation of refresh token request success");
            return(Valid());
        }
Beispiel #16
0
        private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken)
            {
                var error = "Refresh token too long";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                var error = "Refresh token is invalid";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime))
            {
                var error = "Refresh token has expired";
                LogWarn(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                await _refreshTokens.RemoveAsync(refreshTokenHandle);

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId));
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding");

                return(Invalid(Constants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess))
                {
                    var error = "Client does not have access to offline_access scope anymore";
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(Constants.TokenErrors.InvalidGrant));
                }
            }

            /////////////////////////////////////////////
            // check if client still has access to
            // all scopes from the original token request
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                foreach (var scope in refreshToken.Scopes)
                {
                    if (!_validatedRequest.Client.AllowedScopes.Contains(scope))
                    {
                        var error = "Client does not have access to a requested scope anymore: " + scope;
                        LogError(error);
                        await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                        return(Invalid(Constants.TokenErrors.InvalidGrant));
                    }
                }
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims);

            var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client);
            await _users.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(Constants.TokenErrors.InvalidRequest));
            }

            /////////////////////////////////////////////
            // validate token type and PoP parameters if pop token is requested
            /////////////////////////////////////////////
            var tokenType = parameters.Get("token_type");

            if (tokenType != null && tokenType == "pop")
            {
                var result = ValidatePopParameters(parameters);
                if (result.IsError)
                {
                    var error = "PoP parameter validation failed: " + result.ErrorDescription;
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(result.Error, result.ErrorDescription));
                }
                else
                {
                    _validatedRequest.RequestedTokenType = RequestedTokenTypes.PoP;
                }
            }

            Logger.Info("Validation of refresh token request success");
            return(Valid());
        }
        /// <summary>
        /// Issues the login cookie for IdentityServer.
        /// </summary>
        /// <param name="env">The OWIN environment.</param>
        /// <param name="login">The login information.</param>
        /// <exception cref="System.ArgumentNullException">
        /// env
        /// or
        /// login
        /// </exception>
        public static void IssueLoginCookie(this IDictionary <string, object> env, AuthenticatedLogin login)
        {
            if (env == null)
            {
                throw new ArgumentNullException("env");
            }
            if (login == null)
            {
                throw new ArgumentNullException("login");
            }

            var options       = env.ResolveDependency <IdentityServerOptions>();
            var sessionCookie = env.ResolveDependency <SessionCookie>();
            var context       = new OwinContext(env);

            var props = new AuthenticationProperties();

            // if false, then they're explicit in preventing a persistent cookie
            if (login.PersistentLogin != false)
            {
                if (login.PersistentLogin == true || options.AuthenticationOptions.CookieOptions.IsPersistent)
                {
                    props.IsPersistent = true;
                    if (login.PersistentLogin == true)
                    {
                        var expires = login.PersistentLoginExpiration ?? DateTimeHelper.UtcNow.Add(options.AuthenticationOptions.CookieOptions.RememberMeDuration);
                        props.ExpiresUtc = expires;
                    }
                }
            }

            var authenticationMethod = login.AuthenticationMethod;
            var identityProvider     = login.IdentityProvider ?? Constants.BuiltInIdentityProvider;

            if (String.IsNullOrWhiteSpace(authenticationMethod))
            {
                if (identityProvider == Constants.BuiltInIdentityProvider)
                {
                    authenticationMethod = Constants.AuthenticationMethods.Password;
                }
                else
                {
                    authenticationMethod = Constants.AuthenticationMethods.External;
                }
            }

            var user     = IdentityServerPrincipal.Create(login.Subject, login.Name, authenticationMethod, identityProvider, Constants.PrimaryAuthenticationType);
            var identity = user.Identities.First();

            var claims = login.Claims;

            if (claims != null && claims.Any())
            {
                claims = claims.Where(x => !Constants.OidcProtocolClaimTypes.Contains(x.Type));
                claims = claims.Where(x => x.Type != Constants.ClaimTypes.Name);
                identity.AddClaims(claims);
            }

            context.Authentication.SignIn(props, identity);
            sessionCookie.IssueSessionId(login.PersistentLogin, login.PersistentLoginExpiration);
        }
        /// <summary>
        /// Issues the login cookie for IdentityServer.
        /// </summary>
        /// <param name="env">The OWIN environment.</param>
        /// <param name="login">The login information.</param>
        /// <exception cref="System.ArgumentNullException">
        /// env
        /// or
        /// login
        /// </exception>
        public static void IssueLoginCookie(this IDictionary <string, object> env, AuthenticatedLogin login, string partialSignInUrl = null, string loginId = null)
        {
            if (env == null)
            {
                throw new ArgumentNullException("env");
            }
            if (login == null)
            {
                throw new ArgumentNullException("login");
            }

            bool isPartial = !string.IsNullOrEmpty(partialSignInUrl);

            var options       = env.ResolveDependency <IdentityServerOptions>();
            var sessionCookie = env.ResolveDependency <SessionCookie>();
            var context       = new OwinContext(env);

            var props = new AuthenticationProperties();

            //If the login id is empty, populate it from the request query.
            if (string.IsNullOrEmpty(loginId))
            {
                var id = context.Request.Query.Get(Constants.Authentication.SigninQueryParamName);

                if (String.IsNullOrWhiteSpace(id))
                {
                    return;                                //We don't have a login id... Abort.
                }
                loginId = id;
            }

            // if false, then they're explicit in preventing a persistent cookie
            if (login.PersistentLogin != false)
            {
                if (login.PersistentLogin == true || options.AuthenticationOptions.CookieOptions.IsPersistent)
                {
                    props.IsPersistent = true;
                    if (login.PersistentLogin == true)
                    {
                        var expires = login.PersistentLoginExpiration ?? DateTimeHelper.UtcNow.Add(options.AuthenticationOptions.CookieOptions.RememberMeDuration);
                        props.ExpiresUtc = expires;
                    }
                }
            }

            //Populate the authentication metho and identity sources.
            var authenticationMethod = login.AuthenticationMethod;
            var identityProvider     = login.IdentityProvider ?? Constants.BuiltInIdentityProvider;

            if (String.IsNullOrWhiteSpace(authenticationMethod))
            {
                if (identityProvider == Constants.BuiltInIdentityProvider)
                {
                    authenticationMethod = Constants.AuthenticationMethods.Password;
                }
                else
                {
                    authenticationMethod = Constants.AuthenticationMethods.External;
                }
            }

            //Create the identity principal, setting the partial sign in if applicable.
            var user     = IdentityServerPrincipal.Create(login.Subject, login.Name, authenticationMethod, identityProvider, isPartial ? Constants.PartialSignInAuthenticationType : Constants.PrimaryAuthenticationType);
            var identity = user.Identities.First();

            var claims = login.Claims;

            if (claims != null && claims.Any())
            {
                claims = claims.Where(x => !Constants.OidcProtocolClaimTypes.Contains(x.Type));
                claims = claims.Where(x => x.Type != Constants.ClaimTypes.Name);
                identity.AddClaims(claims);
            }

            //Are we a partial sign in?
            if (isPartial)
            {
                // add claim so partial redirect can return here to continue login
                // we need a random ID to resume, and this will be the query string
                // to match a claim added. the claim added will be the original
                // signIn ID.
                var resumeId = IdentityModel.CryptoRandom.CreateUniqueId();

                var resumeLoginUrl   = context.GetPartialLoginResumeUrl(resumeId);
                var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
                identity.AddClaim(resumeLoginClaim);
                identity.AddClaim(new Claim(String.Format(Constants.ClaimTypes.PartialLoginResumeId, resumeId), loginId));

                // add url to start login process over again (which re-triggers preauthenticate)
                var restartUrl = context.GetPartialLoginRestartUrl(loginId);
                identity.AddClaim(new Claim(Constants.ClaimTypes.PartialLoginRestartUrl, restartUrl));
            }
            else
            {
                //We are not - issue the session.
                sessionCookie.IssueSessionId(login.PersistentLogin, login.PersistentLoginExpiration);
            }

            context.Authentication.SignIn(props, identity);
        }
        private IHttpActionResult SignInAndRedirect(
            AuthenticateResult authResult,
            string authenticationMethod,
            string identityProvider,
            long authTime = 0)
        {
            logger.Verbose("[AuthenticationController.SignInAndRedirect] called");

            if (authResult == null)
            {
                throw new ArgumentNullException("authResult");
            }
            if (String.IsNullOrWhiteSpace(authenticationMethod))
            {
                throw new ArgumentNullException("authenticationMethod");
            }
            if (String.IsNullOrWhiteSpace(identityProvider))
            {
                throw new ArgumentNullException("identityProvider");
            }

            var signInMessage = LoadLoginRequestMessage();

            var issuer = authResult.IsPartialSignIn ?
                         Constants.PartialSignInAuthenticationType :
                         Constants.PrimaryAuthenticationType;

            var principal = IdentityServerPrincipal.Create(
                authResult.Subject,
                authResult.Name,
                authenticationMethod,
                identityProvider,
                issuer,
                authTime);

            var id = principal.Identities.First();

            if (authResult.IsPartialSignIn)
            {
                // TODO: put original return URL into cookie with a GUID ID
                // and put the ID as route param for the resume URL. then
                // we can always call ClearLoginRequestMessage()
                id.AddClaim(new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, Url.Route(Constants.RouteNames.ResumeLoginFromRedirect, null)));

                // allow redircting code to add claims for target page
                id.AddClaims(authResult.RedirectClaims);
            }

            var ctx = Request.GetOwinContext();

            ctx.Authentication.SignOut(
                Constants.PrimaryAuthenticationType,
                Constants.ExternalAuthenticationType,
                Constants.PartialSignInAuthenticationType);
            ctx.Authentication.SignIn(id);

            if (authResult.IsPartialSignIn)
            {
                logger.Verbose("[AuthenticationController.SignInAndRedirect] partial login requested, redirecting to requested url");

                var uri = new Uri(ctx.Request.Uri, authResult.PartialSignInRedirectPath.Value);
                return(Redirect(uri));
            }
            else
            {
                logger.Verbose("[AuthenticationController.SignInAndRedirect] normal login requested, redirecting back to authorization");

                // TODO -- manage this state better if we're doing redirect to custom page
                // would rather the redirect URL from request message put into cookie
                // and named with a nonce, then the resume url + nonce set as claim
                // in principal above so page being redirected to can know what url to return to
                ClearLoginRequestMessage();

                return(Redirect(signInMessage.ReturnUrl));
            }
        }
Beispiel #20
0
 public static async Task SignInAsync(this AuthenticationManager manager, string scheme, string sub, string name, string identityProvider, IEnumerable <string> authenticationMethods, AuthenticationProperties properties, params Claim[] claims)
 {
     await manager.SignInAsync(scheme, IdentityServerPrincipal.Create(sub, name, identityProvider, authenticationMethods, claims), properties);
 }
        public async Task GetAllGrantsAsync_should_return_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            await _referenceTokens.StoreReferenceTokenAsync("key1", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key2", new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key3", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3"),
                },
            });

            await _refreshTokens.StoreRefreshTokenAsync("key4", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key5", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key6", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _codes.StoreAuthorizationCodeAsync("key7", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            await _codes.StoreAuthorizationCodeAsync("key8", new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _codes.StoreAuthorizationCodeAsync("key9", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = IdentityServerPrincipal.Create("456", "alice"),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            var grants = await _subject.GetAllGrantsAsync("123");

            grants.Count().Should().Be(2);
            var grant1 = grants.First(x => x.ClientId == "client1");

            grant1.SubjectId.Should().Be("123");
            grant1.ClientId.Should().Be("client1");
            grant1.Scopes.ShouldBeEquivalentTo(new string[] { "foo1", "foo2", "bar1", "bar2", "baz1", "baz2", "quux1", "quux2" });

            var grant2 = grants.First(x => x.ClientId == "client2");

            grant2.SubjectId.Should().Be("123");
            grant2.ClientId.Should().Be("client2");
            grant2.Scopes.ShouldBeEquivalentTo(new string[] { "foo3", "bar3", "baz3", "quux3" });
        }
Beispiel #22
0
        private void IssueAuthenticationCookie(
            AuthenticateResult authResult,
            string authenticationMethod,
            string identityProvider,
            long authTime)
        {
            if (authResult == null)
            {
                throw new ArgumentNullException("authResult");
            }
            if (String.IsNullOrWhiteSpace(authenticationMethod))
            {
                throw new ArgumentNullException("authenticationMethod");
            }
            if (String.IsNullOrWhiteSpace(identityProvider))
            {
                throw new ArgumentNullException("identityProvider");
            }

            Logger.InfoFormat("logging user in as subject: {0}, name: {1}{2}", authResult.Subject, authResult.Name, authResult.IsPartialSignIn ? " (partial login)" : "");

            var issuer = authResult.IsPartialSignIn ?
                         Constants.PartialSignInAuthenticationType :
                         Constants.PrimaryAuthenticationType;

            var principal = IdentityServerPrincipal.Create(
                authResult.Subject,
                authResult.Name,
                authenticationMethod,
                identityProvider,
                issuer,
                authTime);

            var props = new Microsoft.Owin.Security.AuthenticationProperties();

            var id = principal.Identities.First();

            if (authResult.IsPartialSignIn)
            {
                // add claim so partial redirect can return here to continue login
                var resumeLoginUrl   = Url.Link(Constants.RouteNames.ResumeLoginFromRedirect, null);
                var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
                id.AddClaim(resumeLoginClaim);

                // store original authorization url as claim
                // so once we result we can return to authorization page
                var signInMessage         = LoadSignInMessage();
                var authorizationUrl      = signInMessage.ReturnUrl;
                var authorizationUrlClaim = new Claim(Constants.ClaimTypes.AuthorizationReturnUrl, authorizationUrl);
                id.AddClaim(authorizationUrlClaim);

                // allow redircting code to add claims for target page
                id.AddClaims(authResult.RedirectClaims);
            }
            else if (this._options.CookieOptions.IsPersistent)
            {
                props.IsPersistent = true;
            }

            ClearAuthenticationCookies();

            var ctx = Request.GetOwinContext();

            ctx.Authentication.SignIn(props, id);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClaimsPrincipal"/> class with Claims from the Membership User
 /// </summary>
 /// <param name="user">Membership User</param>
 /// <param name="identityProvider">Identity Provider Name</param>
 /// <param name="claims">List of additional claims</param>
 /// <returns>Claims Principal</returns>
 public static ClaimsPrincipal Create(this MembershipUser user, string identityProvider, params Claim[] claims)
 {
     return(IdentityServerPrincipal.Create(user.GetSubjectId(), user.UserName, identityProvider, DateTime.Now, claims));
 }
        private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start validation of refresh token request");

            var refreshTokenHandle = parameters.Get(OidcConstants.TokenRequest.RefreshToken);

            if (refreshTokenHandle.IsMissing())
            {
                var error = "Refresh token is missing";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
            }

            if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken)
            {
                var error = "Refresh token too long";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(null, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.RefreshTokenHandle = refreshTokenHandle;

            /////////////////////////////////////////////
            // check if refresh token is valid
            /////////////////////////////////////////////
            var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle);

            if (refreshToken == null)
            {
                var error = "Refresh token cannot be found in store: " + refreshTokenHandle;
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if refresh token has expired
            /////////////////////////////////////////////
            if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime))
            {
                var error = "Refresh token has expired";
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                await _refreshTokens.RemoveAsync(refreshTokenHandle);

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client belongs to requested refresh token
            /////////////////////////////////////////////
            if (_validatedRequest.Client.ClientId != refreshToken.ClientId)
            {
                LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId));
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding");

                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // check if client still has offline_access scope
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowAccessToAllScopes)
            {
                if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess))
                {
                    var error = "Client does not have access to offline_access scope anymore";
                    LogError(error);
                    await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                    return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
                }
            }

            _validatedRequest.RefreshToken = refreshToken;

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims);

            var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client);
            await _profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId;
                LogError(error);
                await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error);

                return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
            }

            _logger.LogInformation("Validation of refresh token request success");
            return(Valid());
        }
Beispiel #25
0
        public DefaultRefreshTokenServiceTests()
        {
            originalNowFunc = DateTimeOffsetHelper.UtcNowFunc;
            DateTimeOffsetHelper.UtcNowFunc = () => UtcNow;

            roclient_absolute_refresh_expiration_one_time_only = new Client
            {
                ClientName    = "Resource Owner Client",
                Enabled       = true,
                ClientId      = "roclient_absolute_refresh_expiration_one_time_only",
                ClientSecrets = new List <Secret>
                {
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration       = TokenExpiration.Absolute,
                RefreshTokenUsage            = TokenUsage.OneTimeOnly,
                AbsoluteRefreshTokenLifetime = 200
            };

            roclient_sliding_refresh_expiration_one_time_only = new Client
            {
                ClientName    = "Resource Owner Client",
                Enabled       = true,
                ClientId      = "roclient_sliding_refresh_expiration_one_time_only",
                ClientSecrets = new List <Secret>
                {
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration       = TokenExpiration.Sliding,
                RefreshTokenUsage            = TokenUsage.OneTimeOnly,
                AbsoluteRefreshTokenLifetime = 10,
                SlidingRefreshTokenLifetime  = 4
            };

            roclient_absolute_refresh_expiration_reuse = new Client
            {
                ClientName    = "Resource Owner Client",
                Enabled       = true,
                ClientId      = "roclient_absolute_refresh_expiration_reuse",
                ClientSecrets = new List <Secret>
                {
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration       = TokenExpiration.Absolute,
                RefreshTokenUsage            = TokenUsage.ReUse,
                AbsoluteRefreshTokenLifetime = 200
            };

            refreshTokenStore = new InMemoryRefreshTokenStore();
            service           = new DefaultRefreshTokenService(refreshTokenStore, new DefaultEventService());

            user = IdentityServerPrincipal.Create("bob", "Bob Loblaw");
        }
Beispiel #26
0
        private async Task <string> GetToken(string userName, string audience)
        {
            var Request = new TokenCreationRequest();
            var User    = await _userManager.FindByNameAsync(userName);

            var IdentityPricipal = await _principalFactory.CreateAsync(User);

            var IdServerPrincipal = IdentityServerPrincipal.Create(User.Id.ToString(), User.UserName, IdentityPricipal.Claims.ToArray());

            var lstScope = new List <Scope>
            {
                new Scope
                {
                    Name       = "api.main",
                    Emphasize  = true,
                    UserClaims = new List <string>
                    {
                        "role",
                        "name"
                    }
                },
                new Scope
                {
                    Name       = "api.blockchain",
                    Emphasize  = true,
                    UserClaims = new List <string>
                    {
                        "role",
                        "name"
                    }
                }
            };

            var c1 = new IdentityServer4.Models.Client
            {
                ClientId        = "generatedTokenClient",
                ClientName      = "generatedTokenClient",
                Enabled         = true,
                AccessTokenType = AccessTokenType.Jwt,
                ClientSecrets   = new List <IdentityServer4.Models.Secret>
                {
                    new IdentityServer4.Models.Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256())
                }
            };

            Request.Subject = IdServerPrincipal;
            Request.IncludeAllIdentityClaims = true;
            Request.ValidatedRequest         = new ValidatedRequest();
            Request.ValidatedRequest.Subject = Request.Subject;
            Request.ValidatedRequest.SetClient(c1);

            Request.Resources = new Resources(Config.GetIdentityResources(), Config.GetApiResources());
            Request.ValidatedRequest.Options      = _option;
            Request.ValidatedRequest.ClientClaims = IdentityPricipal.Claims.ToArray();

            var Token = await _ts.CreateAccessTokenAsync(Request);

            Token.Issuer    = "https://" + HttpContext.Request.Host.Value;
            Token.Audiences = new List <string> {
                audience
            };

            if (Token.Claims == null)
            {
                Token.Claims = new List <Claim>();
            }

            var rolesClaim = IdentityPricipal.FindAll("role");

            if (rolesClaim != null && rolesClaim.Count() > 0)
            {
                foreach (var r1 in rolesClaim)
                {
                    Token.Claims.Add(r1);
                }
            }

            var nameClaim = IdentityPricipal.FindFirst("name");

            if (nameClaim != null)
            {
                Token.Claims.Add(nameClaim);
            }

            var custIdClaim = IdentityPricipal.FindFirst("customerid");

            if (custIdClaim != null)
            {
                Token.Claims.Add(custIdClaim);
            }

            var TokenValue = await _ts.CreateSecurityTokenAsync(Token);

            return(TokenValue);
        }
 public DefaultUserSessionTests()
 {
     _user    = IdentityServerPrincipal.Create("123", "bob");
     _subject = new DefaultUserSession(_mockHttpContext, _options, TestLogger.Create <DefaultUserSession>());
 }