public void SuccessfulResourceOwnerRevocation()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("client", "client"),
                    Fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting auth token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "openid" }, "pwd"))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then can revoke token".x(
                async() =>
            {
                var response = await client.RevokeToken(RevokeTokenRequest.Create(result)).ConfigureAwait(false);
                Assert.IsType <Option.Success>(response);
            });
        }
        public void SuccessfulResourceOwnerRefresh()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("clientCredentials", "clientCredentials"),
                    Fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting auth token".x(
                async() =>
            {
                var response =
                    await client.GetToken(TokenRequest.FromScopes("api1", "offline")).ConfigureAwait(false) as
                    Option <GrantedTokenResponse> .Result;

                Assert.NotNull(response);

                result = response !.Item;
            });

            "then can get new token from refresh token".x(
                async() =>
            {
                var response = await client.GetToken(TokenRequest.FromRefreshToken(result.RefreshToken !))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                Assert.NotNull(response);
            });
        }
Beispiel #3
0
        public void SuccessfulResourceOwnerRevocation()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting auth token".x(
                async() =>
            {
                var response =
                    await client.GetToken(TokenRequest.FromScopes("api1", "offline")).ConfigureAwait(false) as
                    Option <GrantedTokenResponse> .Result;

                Assert.NotNull(response);

                result = response.Item;
            });

            "then can revoke token".x(
                async() =>
            {
                var response = await client.RevokeToken(RevokeTokenRequest.Create(result)).ConfigureAwait(false);
                Assert.IsType <Option.Success>(response);
            });
        }
        public void SuccessfulPermissionCreation()
        {
            GrantedTokenResponse grantedToken = null !;
            UmaClient            client       = null !;
            JsonWebKeySet        jwks         = null !;
            string resourceId = null !;
            string ticketId   = null !;

            "and the server's signing key".x(
                async() =>
            {
                var json = await _fixture.Client().GetStringAsync(BaseUrl + "/jwks").ConfigureAwait(false);
                jwks     = new JsonWebKeySet(json);

                Assert.NotEmpty(jwks.Keys);
            });

            "and a valid UMA token".x(
                async() =>
            {
                var tokenClient = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    _fixture.Client,
                    new Uri(WellKnownUmaConfiguration));
                var token = await tokenClient.GetToken(TokenRequest.FromScopes("uma_protection"))
                            .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                grantedToken = token !.Item;
            });

            "and a properly configured uma client".x(
                () => client = new UmaClient(_fixture.Client, new Uri(WellKnownUmaConfiguration)));

            "when registering resource".x(
                async() =>
            {
                var resource = await client.AddResource(
                    new ResourceSet {
                    Name = "picture", Scopes = new[] { "read" }
                },
                    grantedToken.AccessToken)
                               .ConfigureAwait(false) as Option <AddResourceSetResponse> .Result;
                resourceId = resource.Item.Id;
            });

            "and adding permission".x(
                async() =>
            {
                var response = await client.RequestPermission(
                    grantedToken.AccessToken,
                    requests: new PermissionRequest {
                    ResourceSetId = resourceId, Scopes = new[] { "read" }
                })
                               .ConfigureAwait(false) as Option <TicketResponse> .Result;

                ticketId = response !.Item.TicketId;
            });

            "then returns ticket id".x(() => { Assert.NotNull(ticketId); });
        }
        public void SuccessfulMultiplePermissionsCreation()
        {
            GrantedTokenResponse grantedToken = null !;
            UmaClient            client       = null !;
            string resourceId = null !;
            string ticketId   = null !;

            "and a valid UMA token".x(
                async() =>
            {
                var tokenClient = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    Fixture.Client,
                    new Uri(WellKnownUmaConfiguration));
                var token = await tokenClient.GetToken(TokenRequest.FromScopes("uma_protection"))
                            .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                grantedToken = token !.Item;

                Assert.NotNull(grantedToken);
            });

            "and a properly configured uma client".x(
                () => client = new UmaClient(Fixture.Client, new Uri(WellKnownUmaConfiguration)));

            "when registering resource".x(
                async() =>
            {
                var resource = await client.AddResource(
                    new ResourceSet {
                    Name = "picture", Scopes = new[] { "read", "write" }
                },
                    grantedToken.AccessToken)
                               .ConfigureAwait(false) as Option <AddResourceSetResponse> .Result;
                resourceId = resource !.Item.Id;

                Assert.NotNull(resourceId);
            });

            "and adding permission".x(
                async() =>
            {
                var response = await client.RequestPermission(
                    grantedToken.AccessToken,
                    CancellationToken.None,
                    new PermissionRequest {
                    ResourceSetId = resourceId, Scopes = new[] { "write" }
                },
                    new PermissionRequest {
                    ResourceSetId = resourceId, Scopes = new[] { "read" }
                })
                               .ConfigureAwait(false) as Option <TicketResponse> .Result;

                ticketId = response !.Item.TicketId;

                Assert.NotNull(ticketId);
            });

            "then returns ticket id".x(() => { Assert.NotNull(ticketId); });
        }
Beispiel #6
0
        public void SuccessfulResourceOwnerAuthentication()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("client", "client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "openid" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;

                Assert.NotNull(response);

                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "and has valid id token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = TestKeys.SecretKey.CreateJwk(
                        JsonWebKeyUseNames.Sig,
                        KeyOperations.Sign,
                        KeyOperations.Verify),
                    ValidAudience = "client",
                    ValidIssuer   = "https://localhost"
                };
                tokenHandler.ValidateToken(result.IdToken, validationParameters, out _);
            });
        }
Beispiel #7
0
        public void UserinfoAfterSuccessfulResourceOwnerAuthentication()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("client", "client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "openid" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "and can get user info".x(
                async() =>
            {
                var userinfoRequest = new HttpRequestMessage
                {
                    Method = HttpMethod.Get, RequestUri = new Uri(BaseUrl + "/userinfo")
                };
                userinfoRequest.Headers.Authorization =
                    new AuthenticationHeaderValue(result.TokenType, result.AccessToken);
                var userinfo = await _fixture.Client().SendAsync(userinfoRequest).ConfigureAwait(false);

                Assert.True(userinfo.IsSuccessStatusCode);
            });
        }
Beispiel #8
0
        public void SuccessfulTokenValidationFromMetadata()
        {
            GrantedTokenResponse tokenResponse = null !;
            JsonWebKeySet        jwks          = null !;

            "And a valid token".x(
                async() =>
            {
                var tokenClient = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    Fixture.Client,
                    new Uri(WellKnownOpenidConfiguration));
                var response =
                    await tokenClient.GetToken(TokenRequest.FromScopes("api1")).ConfigureAwait(false) as
                    Option <GrantedTokenResponse> .Result;

                Assert.NotNull(response);

                tokenResponse = response.Item;
            });

            "then can download json web key set".x(
                async() =>
            {
                var jwksJson = await Fixture.Client().GetStringAsync(BaseUrl + "/jwks").ConfigureAwait(false);

                Assert.NotNull(jwksJson);

                jwks = JsonWebKeySet.Create(jwksJson);
            });

            "Then can create token validation parameters from service metadata".x(
                () =>
            {
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = jwks.Keys,
                    ValidIssuer       = "https://localhost",
                    ValidAudience     = "clientCredentials"
                };

                var handler = new JwtSecurityTokenHandler();

                handler.ValidateToken(tokenResponse.AccessToken, validationParameters, out var securityToken);

                Assert.NotNull(securityToken);
            });
        }
        public void SuccessfulClientCredentialsAuthentication()
        {
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response =
                    await client.GetToken(TokenRequest.FromScopes("api1")).ConfigureAwait(false) as
                    Option <GrantedTokenResponse> .Result;

                Assert.NotNull(response);

                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "clientCredentials",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);
            });

            "and can get user info".x(
                async() =>
            {
                var userinfo = await client.GetUserInfo(result.AccessToken).ConfigureAwait(false) as Option <JwtPayload> .Result;

                Assert.NotNull(userinfo);
                Assert.NotNull(userinfo.Item);
            });
        }
        public void WhenClientHasNoSigningKeysThenUsesServerKey()
        {
            TokenClient          client = null !;
            GrantedTokenResponse token  = null !;

            "Given a token client".x(
                () =>
            {
                client = new TokenClient(
                    TokenCredentials.FromClientCredentials("no_key", "no_key"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration));
            });

            "When getting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("administrator", "password", new[] { "api" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                token = response.Item;

                Assert.NotNull(token);
            });

            "Then token is signed with server key".x(
                () =>
            {
                var key = _jwks.GetSignKeys().First();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey    = key,
                    ValidateAudience    = false,
                    ValidateActor       = false,
                    ValidateIssuer      = false,
                    ValidateLifetime    = false,
                    ValidateTokenReplay = false
                };
                var handler = new JwtSecurityTokenHandler();
                handler.ValidateToken(token.IdToken, validationParameters, out _);
            });
        }
Beispiel #11
0
        public void SuccessfulResourceOwnerRefresh()
        {
            TokenClient          client    = null !;
            GrantedTokenResponse result    = null !;
            GrantedTokenResponse refreshed = null !;

            "and a properly token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("client", "client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting auth token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "openid", "offline" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then can get new token from refresh token".x(
                async() =>
            {
                var response = await client.GetToken(TokenRequest.FromRefreshToken(result.RefreshToken))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                Assert.NotNull(response);

                refreshed = response.Item;
            });

            "and token has custom custom claims".x(
                () =>
            {
                var handler         = new JwtSecurityTokenHandler();
                var refreshedClaims = handler.ReadJwtToken(refreshed.AccessToken).Claims;

                Assert.Contains(refreshedClaims, c => c.Type == "acceptance_test");
            });
        }
        public void ManagerCreatedUser()
        {
            GrantedTokenResponse userToken = null !;

            "When manager creates user".x(
                async() =>
            {
                var created = await _managerClient.AddResourceOwner(
                    new AddResourceOwnerRequest {
                    Subject = "tester", Password = "******"
                },
                    _administratorToken.AccessToken)
                              .ConfigureAwait(false) as Option <AddResourceOwnerResponse> .Result;

                Assert.Equal("tester", created.Item.Subject);
            });

            "and user logs in".x(
                async() =>
            {
                var response = await _tokenClient
                               .GetToken(TokenRequest.FromPassword("tester", "tester", new[] { "openid" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;

                userToken = response.Item;
            });

            "then user has custom user claim".x(
                () =>
            {
                var handler = new JwtSecurityTokenHandler();
                handler.ValidateToken(
                    userToken.AccessToken,
                    new NoOpTokenValidationParameters(SharedContext.Instance),
                    out var token);

                Assert.Contains((token as JwtSecurityToken).Claims, c => c.Type == "acceptance_test");
            });
        }
        public void SuccessfulPermissionCreation()
        {
            TestServerFixture    fixture      = null !;
            GrantedTokenResponse grantedToken = null !;
            UmaClient            client       = null !;
            string resourceId = null !;
            string ticketId   = null !;

            "Given a running auth server".x(() => fixture = new TestServerFixture(_outputHelper, BaseUrl))
            .Teardown(() => fixture.Dispose());

            "and the server's signing key".x(
                async() =>
            {
                var json = await fixture.Client().GetStringAsync(BaseUrl + "/jwks").ConfigureAwait(false);
                var jwks = new JsonWebKeySet(json);

                Assert.NotEmpty(jwks.Keys);
            });

            "and a valid UMA token".x(
                async() =>
            {
                var tokenClient = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    fixture.Client,
                    new Uri(WellKnownUmaConfiguration));
                var token = await tokenClient.GetToken(TokenRequest.FromScopes("uma_protection"))
                            .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                var handler   = new JwtSecurityTokenHandler();
                var principal = handler.ReadJwtToken(token.Item.AccessToken);
                Assert.NotNull(principal.Issuer);
                grantedToken = token.Item;
            });

            "and a properly configured uma client".x(
                () => client = new UmaClient(fixture.Client, new Uri(WellKnownUmaConfiguration)));

            "when registering resource".x(
                async() =>
            {
                var resource = await client.AddResource(
                    new ResourceSet {
                    Name = "picture", Scopes = new[] { "read" }
                },
                    grantedToken.AccessToken)
                               .ConfigureAwait(false) as Option <AddResourceSetResponse> .Result;
                resourceId = resource.Item.Id;
            });

            "and adding permission".x(
                async() =>
            {
                var response = await client.RequestPermission(
                    grantedToken.AccessToken,
                    requests: new PermissionRequest {
                    IdToken = grantedToken.IdToken, ResourceSetId = resourceId, Scopes = new[] { "read" }
                })
                               .ConfigureAwait(false) as Option <TicketResponse> .Result;

                Assert.NotNull(response);

                ticketId = response.Item.TicketId;
            });

            "then returns ticket id".x(() => { Assert.NotNull(ticketId); });
        }
Beispiel #14
0
        public void SuccessfulResourceOwnerClaimsUpdate()
        {
            TokenClient          client         = null !;
            GrantedTokenResponse tokenResponse  = null !;
            HttpResponseMessage  updateResponse = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromBasicAuthentication("client", "client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "openid", "offline" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                tokenResponse = response.Item;
            });

            "and valid access token is received".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(tokenResponse.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "and updating own claims".x(
                async() =>
            {
                var updateRequest = new UpdateResourceOwnerClaimsRequest
                {
                    Subject = "user", Claims = new[] { new ClaimData {
                                                           Type = "test", Value = "something"
                                                       } }
                };

                var json = JsonConvert.SerializeObject(updateRequest);

                var request = new HttpRequestMessage
                {
                    Content    = new StringContent(json, Encoding.UTF8, "application/json"),
                    Method     = HttpMethod.Post,
                    RequestUri = new Uri(_fixture.Server.BaseAddress + "resource_owners/claims")
                };
                request.Headers.Authorization = new AuthenticationHeaderValue(
                    JwtBearerDefaults.AuthenticationScheme,
                    tokenResponse.AccessToken);
                updateResponse = await _fixture.Client().SendAsync(request).ConfigureAwait(false);
            });

            "then update is successful".x(() => { Assert.Equal(HttpStatusCode.OK, updateResponse.StatusCode); });
        }
        public void CanRegisterAResourceForUserAndManagePolicies()
        {
            TokenClient            client              = null !;
            UmaClient              umaClient           = null !;
            GrantedTokenResponse   token               = null !;
            AddResourceSetResponse resourceSetResponse = null !;
            EditPolicyResponse     policyRules         = null !;

            "Given a token client".x(
                () =>
            {
                client = new TokenClient(
                    TokenCredentials.FromClientCredentials("clientCredentials", "clientCredentials"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration));
            });

            "And a UMA client".x(() => { umaClient = new UmaClient(_fixture.Client, new Uri(BaseUrl)); });

            "When getting a PAT token".x(
                async() =>
            {
                var response = await client.GetToken(
                    TokenRequest.FromPassword("administrator", "password", new[] { "uma_protection" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                token = response.Item;

                Assert.NotNull(token);
            });

            "Then can register a resource".x(
                async() =>
            {
                var resource = new ResourceSet
                {
                    AuthorizationPolicies = new[]
                    {
                        new PolicyRule
                        {
                            ClientIdsAllowed             = new[] { "clientCredentials" },
                            IsResourceOwnerConsentNeeded = true,
                            Scopes = new[] { "read" }
                        }
                    },
                    Name   = "test resource",
                    Scopes = new[] { "read" },
                    Type   = "test"
                };
                var response = await umaClient.AddResource(resource, token.AccessToken).ConfigureAwait(false) as Option <AddResourceSetResponse> .Result;

                Assert.NotNull(response);

                resourceSetResponse = response.Item;
            });

            "And can view resource policies".x(
                async() =>
            {
                var msg = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(resourceSetResponse.UserAccessPolicyUri)
                };
                msg.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                msg.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);

                var policyResponse = await _fixture.Client().SendAsync(msg).ConfigureAwait(false);

                Assert.True(policyResponse.IsSuccessStatusCode);

                var content = await policyResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                policyRules = JsonConvert.DeserializeObject <EditPolicyResponse>(content);

                Assert.Single(policyRules !.Rules);
            });

            "And can update resource policies".x(
                async() =>
            {
                policyRules.Rules[0] = policyRules.Rules[0] with {
                    IsResourceOwnerConsentNeeded = false
                };

                var msg = new HttpRequestMessage
                {
                    Method     = HttpMethod.Put,
                    RequestUri = new Uri(resourceSetResponse.UserAccessPolicyUri),
                    Content    = new StringContent(JsonConvert.SerializeObject(policyRules))
                };
                msg.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);

                var policyResponse = await _fixture.Client().SendAsync(msg).ConfigureAwait(false);

                Assert.True(policyResponse.IsSuccessStatusCode);
            });
        }
Beispiel #16
0
        public void CanUpdateOwnClaimsAndLogInAgain()
        {
            HttpResponseMessage  response     = null !;
            GrantedTokenResponse updatedToken = null !;
            GrantedTokenResponse newToken     = null !;

            "When updating user claims".x(
                async() =>
            {
                var updateRequest = new UpdateResourceOwnerClaimsRequest
                {
                    Subject = "administrator",
                    Claims  = new[] { new ClaimData {
                                          Type = "added_claim_test", Value = "something"
                                      } }
                };

                var json = JsonConvert.SerializeObject(updateRequest);

                var request = new HttpRequestMessage
                {
                    Content    = new StringContent(json, Encoding.UTF8, "application/json"),
                    Method     = HttpMethod.Post,
                    RequestUri = new Uri(_fixture.Server.BaseAddress + "resource_owners/claims")
                };
                request.Headers.Authorization = new AuthenticationHeaderValue(
                    "Bearer",
                    _administratorToken.AccessToken);
                response = await _fixture.Client().SendAsync(request).ConfigureAwait(false);
            });

            "Then is ok request".x(() => { Assert.Equal(HttpStatusCode.OK, response.StatusCode); });

            "and has new token".x(
                async() =>
            {
                var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                updatedToken = JsonConvert.DeserializeObject <GrantedTokenResponse>(json);

                Assert.NotNull(updatedToken);
            });

            "When logging out".x(
                async() =>
            {
                var result = await _tokenClient.RevokeToken(RevokeTokenRequest.Create(updatedToken))
                             .ConfigureAwait(false);
                Assert.IsType <Option.Success>(result);
            });

            "and logging in again".x(
                async() =>
            {
                var result = await _tokenClient
                             .GetToken(TokenRequest.FromPassword("administrator", "password", new[] { "manager" }))
                             .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;

                Assert.NotNull(result);

                newToken = result.Item;
            });

            "then gets updated claim in token".x(
                () =>
            {
                var handler    = new JwtSecurityTokenHandler();
                var updatedJwt = handler.ReadJwtToken(updatedToken.AccessToken);
                var newJwt     = handler.ReadJwtToken(newToken.AccessToken);

                Assert.Equal(
                    updatedJwt.Claims.First(x => x.Type == "added_claim_test").Value,
                    newJwt.Claims.First(x => x.Type == "added_claim_test").Value);
            });
        }
        public void SuccessfulTicketAuthentication()
        {
            GrantedTokenResponse   umaToken            = null !;
            AddResourceSetResponse resourceSetResponse = null !;
            UmaClient            umaClient             = null !;
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;
            string ticketId             = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromClientCredentials("post_client", "post_client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "uma_protection", "offline" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "post_client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "given a uma client".x(
                () =>
            {
                umaClient = new UmaClient(
                    _fixture.Client,
                    new Uri("https://localhost/.well-known/uma2-configuration"));
            });

            "when creating resource set".x(
                async() =>
            {
                var resourceSet = new ResourceSet {
                    Name = "Local", Scopes = new[] { "api1" }, Type = "url",
                };

                var resourceResponse =
                    await umaClient.AddResource(resourceSet, result.AccessToken).ConfigureAwait(false) as
                    Option <AddResourceSetResponse> .Result;
                resourceSetResponse = resourceResponse.Item;

                Assert.NotNull(resourceResponse);
            });

            "and setting access policy".x(
                async() =>
            {
                var resourceSet = new ResourceSet
                {
                    Id     = resourceSetResponse.Id,
                    Name   = "Local",
                    Scopes = new[] { "api1" },
                    Type   = "url",
                    AuthorizationPolicies = new[]
                    {
                        new PolicyRule
                        {
                            Scopes = new[] { "api1" },
                            Claims = new[]
                            {
                                new ClaimData {
                                    Type = ClaimTypes.NameIdentifier, Value = "user"
                                }
                            },
                            ClientIdsAllowed             = new[] { "post_client" },
                            IsResourceOwnerConsentNeeded = false
                        }
                    }
                };
                var resourceResponse =
                    await umaClient.UpdateResource(resourceSet, result.AccessToken).ConfigureAwait(false) as
                    Option <UpdateResourceSetResponse> .Result;

                Assert.NotNull(resourceResponse);
            });

            "then can get redirection".x(
                async() =>
            {
                var request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri("http://localhost/data/" + resourceSetResponse.Id)
                };
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

                var response = await _fixture.Client().SendAsync(request).ConfigureAwait(false);

                Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                var httpHeaderValueCollection = response.Headers.WwwAuthenticate;
                Assert.True(httpHeaderValueCollection != null);

                var match = Regex.Match(
                    httpHeaderValueCollection.First().Parameter,
                    ".+ticket=\"(.+)\".*",
                    RegexOptions.Compiled);
                ticketId = match.Groups[1].Value;
            });

            "when requesting token".x(
                async() =>
            {
                var response = await client.GetToken(TokenRequest.FromTicketId(ticketId, result.IdToken))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                umaToken = response.Item;

                Assert.NotNull(umaToken.AccessToken);
            });

            "then can get resource with token".x(
                async() =>
            {
                var request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri("http://localhost/data/" + resourceSetResponse.Id)
                };
                request.Headers.Authorization = new AuthenticationHeaderValue(
                    umaToken.TokenType,
                    umaToken.AccessToken);
                var response = await _fixture.Client().SendAsync(request).ConfigureAwait(false);
                var content  = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Equal("\"Hello\"", content);
            });
        }
        public void UnsuccessfulTicketAuthentication()
        {
            Option <GrantedTokenResponse> ticketResponse      = null !;
            AddResourceSetResponse        resourceSetResponse = null !;
            UmaClient            umaClient = null !;
            TokenClient          client    = null !;
            GrantedTokenResponse result    = null !;
            string ticketId = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromClientCredentials("post_client", "post_client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "uma_protection" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "post_client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "given a uma client".x(
                () =>
            {
                umaClient = new UmaClient(
                    _fixture.Client,
                    new Uri("https://localhost/.well-known/uma2-configuration"));
            });

            "when creating resource set with deviating scopes".x(
                async() =>
            {
                var resourceSet = new ResourceSet
                {
                    Name   = "Local",
                    Scopes = new[] { "api1" },
                    Type   = "url",
                    AuthorizationPolicies = new[]
                    {
                        new PolicyRule
                        {
                            Scopes = new[] { "anotherApi" },
                            Claims = new[] { new ClaimData {
                                                 Type = "sub", Value = "user"
                                             } },
                            ClientIdsAllowed             = new[] { "post_client" },
                            IsResourceOwnerConsentNeeded = false
                        }
                    }
                };

                var resourceResponse =
                    await umaClient.AddResource(resourceSet, result.AccessToken).ConfigureAwait(false) as
                    Option <AddResourceSetResponse> .Result;

                Assert.NotNull(resourceResponse);

                resourceSetResponse = resourceResponse.Item;
            });

            "and requesting permission ticket".x(
                async() =>
            {
                var permission =
                    new PermissionRequest {
                    ResourceSetId = resourceSetResponse.Id, Scopes = new[] { "api1" }
                };
                var permissionResponse = await umaClient.RequestPermission(result.AccessToken, requests: permission)
                                         .ConfigureAwait(false) as Option <TicketResponse> .Result;

                Assert.NotNull(permissionResponse);

                ticketId = permissionResponse.Item.TicketId;
            });

            "and requesting token from ticket".x(
                async() =>
            {
                ticketResponse = await client.GetToken(TokenRequest.FromTicketId(ticketId, result.IdToken))
                                 .ConfigureAwait(false);
            });

            "then has error".x(() => { Assert.IsType <Option <GrantedTokenResponse> .Error>(ticketResponse); });
        }
        public void DefaultPolicyTicketAuthentication()
        {
            AddResourceSetResponse resourceSetResponse = null !;
            UmaClient            umaClient             = null !;
            TokenClient          client = null !;
            GrantedTokenResponse result = null !;
            string ticketId             = null !;

            "and a properly configured token client".x(
                () => client = new TokenClient(
                    TokenCredentials.FromClientCredentials("post_client", "post_client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration)));

            "when requesting token".x(
                async() =>
            {
                var response = await client
                               .GetToken(TokenRequest.FromPassword("user", "password", new[] { "uma_protection" }))
                               .ConfigureAwait(false) as Option <GrantedTokenResponse> .Result;
                result = response.Item;
            });

            "then has valid access token".x(
                () =>
            {
                var tokenHandler         = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeys = _jwks.GetSigningKeys(),
                    ValidAudience     = "post_client",
                    ValidIssuer       = "https://localhost"
                };
                tokenHandler.ValidateToken(result.AccessToken, validationParameters, out var token);

                Assert.NotEmpty(((JwtSecurityToken)token).Claims);
            });

            "given a uma client".x(
                () => { umaClient = new UmaClient(_fixture.Client, new Uri("https://localhost/")); });

            "when creating resource set without a policy".x(
                async() =>
            {
                var resourceSet = new ResourceSet
                {
                    Name = "Local", Scopes = new[] { "api1" }, Type = "url", AuthorizationPolicies = null
                };

                var resourceResponse =
                    await umaClient.AddResource(resourceSet, result.AccessToken).ConfigureAwait(false) as
                    Option <AddResourceSetResponse> .Result;
                resourceSetResponse = resourceResponse.Item;

                Assert.NotNull(resourceResponse);
            });

            "then can get redirection".x(
                async() =>
            {
                var request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri("http://localhost/data/" + resourceSetResponse.Id)
                };
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

                var response = await _fixture.Client().SendAsync(request).ConfigureAwait(false);

                Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                var httpHeaderValueCollection = response.Headers.WwwAuthenticate;
                Assert.True(httpHeaderValueCollection != null);

                var match = Regex.Match(
                    httpHeaderValueCollection.First().Parameter,
                    ".+ticket=\"(.+)\".*",
                    RegexOptions.Compiled);
                ticketId = match.Groups[1].Value;
            });

            "when requesting token".x(
                async() =>
            {
                var response = await client.GetToken(TokenRequest.FromTicketId(ticketId, result.IdToken))
                               .ConfigureAwait(false);

                Assert.IsType <Option <GrantedTokenResponse> .Error>(response);
            });
        }
        public void ExecuteDeviceAuthorizationFlowWithUserApproval()
        {
            const string clientId    = "device";
            ITokenClient tokenClient = null !;
            DeviceAuthorizationResponse           response    = null !;
            GrantedTokenResponse                  token       = null !;
            Task <Option <GrantedTokenResponse> > pollingTask = null !;

            "Given a token client".x(
                () =>
            {
                tokenClient = new TokenClient(
                    TokenCredentials.AsDevice(),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration));

                Assert.NotNull(tokenClient);
            });

            "and an access token".x(
                async() =>
            {
                var authClient = new TokenClient(
                    TokenCredentials.FromClientCredentials(clientId, "client"),
                    _fixture.Client,
                    new Uri(WellKnownOpenidConfiguration));
                var tokenResponse = await authClient.GetToken(
                    TokenRequest.FromPassword("user", "password", new[] { "openid" }))
                                    .ConfigureAwait(false);

                Assert.IsType <Option <GrantedTokenResponse> .Result>(tokenResponse);

                token = (tokenResponse as Option <GrantedTokenResponse> .Result).Item;
            });

            "When a device requests authorization".x(
                async() =>
            {
                var genericResponse = await tokenClient.GetAuthorization(new DeviceAuthorizationRequest(clientId))
                                      .ConfigureAwait(false);

                Assert.IsType <Option <DeviceAuthorizationResponse> .Result>(genericResponse);

                response = (genericResponse as Option <DeviceAuthorizationResponse> .Result).Item;
            });

            "and the device polls the token server".x(
                async() =>
            {
                pollingTask = tokenClient.GetToken(
                    TokenRequest.FromDeviceCode(clientId, response.DeviceCode, response.Interval));

                Assert.False(pollingTask.IsCompleted);
            });

            "and user successfully posts user code".x(
                async() =>
            {
                var client = _fixture.Client();
                var msg    = new HttpRequestMessage
                {
                    Method     = HttpMethod.Post,
                    RequestUri = new Uri(response.VerificationUri),
                    Content    = new FormUrlEncodedContent(
                        new[] { new KeyValuePair <string, string>("code", response.UserCode) })
                };
                msg.Headers.Authorization = new AuthenticationHeaderValue(token.TokenType, token.AccessToken);

                var approval = await client.SendAsync(msg).ConfigureAwait(false);

                Assert.Equal(HttpStatusCode.OK, approval.StatusCode);
            });

            "then token is returned from polling".x(
                async() =>
            {
                var tokenResponse = await pollingTask.ConfigureAwait(false);

                Assert.IsType <Option <GrantedTokenResponse> .Result>(tokenResponse);
            });
        }