public async Task When_Doesnt_have_Permission_To_Access_To_Scope_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicies = new List <Policy> { new Policy { Scopes = new List <string> { "read" } } }; // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies }, ticket, null); // ASSERT Assert.True(result.IsValid == false); }
public async Task When_Doesnt_have_Permission_To_Access_To_Scope_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter("client_id") { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { Scopes = new List <string> { "read" } } } }; // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, null); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.NotAuthorized); }
public async Task When_AuthorizationPassed_Then_Authorization_Is_Returned() { var ticket = new TicketLineParameter("client_id") { IsAuthorizedByRo = true, Scopes = new[] { "create" } }; var authorizationPolicy = new[] { new PolicyRule { ClientIdsAllowed = new[] { "client_id" }, IsResourceOwnerConsentNeeded = true, Scopes = new[] { "create" } } }; var result = await _authorizationPolicy.Execute( ticket, UmaConstants.IdTokenType, new ClaimsPrincipal(new ClaimsIdentity(Array.Empty <Claim>())), CancellationToken.None, authorizationPolicy) .ConfigureAwait(false); Assert.Equal(AuthorizationPolicyResultKind.Authorized, result.Result); }
public async Task When_AuthorizationPassed_Then_Authorization_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "create" } }; var authorizationPolicies = new List <Policy> { new Policy { IsResourceOwnerConsentNeeded = false, Scopes = new List <string> { "create" } } }; // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies, AcceptPendingRequest = false }, ticket, null); // ASSERT Assert.True(result.IsValid); }
private static AuthorizationPolicyResult ExecuteAuthorizationPolicyRule( TicketLineParameter ticketLineParameter, PolicyRule authorizationPolicy, ClaimsPrincipal requester, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // 1. Check can access to the scope if (ticketLineParameter.Scopes.Any(s => !authorizationPolicy.Scopes.Contains(s))) { return(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.NotAuthorized, requester)); } // 2. Check clients are correct var clientAuthorizationResult = authorizationPolicy.ClientIdsAllowed.Contains(ticketLineParameter.ClientId); if (!clientAuthorizationResult) { return(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.NotAuthorized, requester)); } // 4. Check the resource owner consent is needed if (authorizationPolicy.IsResourceOwnerConsentNeeded && !ticketLineParameter.IsAuthorizedByRo) { return(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.RequestSubmitted, requester)); } // 3. Check claims are correct var claimAuthorizationResult = CheckClaims(authorizationPolicy, requester); return(claimAuthorizationResult.Result != AuthorizationPolicyResultKind.Authorized ? claimAuthorizationResult : new AuthorizationPolicyResult(AuthorizationPolicyResultKind.Authorized, requester)); }
public async Task When_JwsPayload_Cannot_Be_Extracted_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicies = new List <Policy> { new Policy { Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "name" }, new Claim { Type = "email" } } } }; var claimTokenParameters = new ClaimTokenParameter { Format = "http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken", Token = "token" }; _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult((JwsPayload)null)); // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies }, ticket, claimTokenParameters); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.True(error.Type == AuthorizationPolicyResultEnum.NeedInfo); }
public async Task When_RequestAlreadyExists_Then_RequestNotConfirmed_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "create" } }; var authorizationPolicies = new List <Policy> { new Policy { IsResourceOwnerConsentNeeded = true, Scopes = new List <string> { "bad_scope" } } }; _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(new JwsPayload { { "sub", "subject" }, { "name", "bad_name" } })); _pendingRequestRepositorySub.Setup(v => v.Get(It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult((IEnumerable <PendingRequest>) new List <PendingRequest> { new PendingRequest { IsConfirmed = true, Scopes = new List <string> { "create" } } })); // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies, AcceptPendingRequest = true }, ticket, null); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.Equal(AuthorizationPolicyResultEnum.RequestNotConfirmed, error.Type); }
public async Task When_Client_Is_Not_Allowed_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicies = new List <Policy> { new Policy { ClientIds = new List <string> { "client_id" }, Scopes = new List <string> { "read", "create", "update" } } }; // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies }, ticket, null); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.True(error.Type == AuthorizationPolicyResultEnum.NotAuthorized); }
private async Task <AuthorizationPolicyResult> Validate( TicketLineParameter ticketLineParameter, ResourceSet resource, string?claimTokenFormat, ClaimsPrincipal requester, CancellationToken cancellationToken) { if (resource.AuthorizationPolicies.Length == 0) { return(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.RequestSubmitted, requester)); } return(await _authorizationPolicy.Execute( ticketLineParameter, claimTokenFormat, requester, cancellationToken, resource.AuthorizationPolicies) .ConfigureAwait(false)); }
public async Task When_ResourceOwnerConsent_Is_Required_Then_RequestSubmitted_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter("client_id") { IsAuthorizedByRo = false, Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { ClientIdsAllowed = new List <string> { "client_id" }, IsResourceOwnerConsentNeeded = true, Scopes = new List <string> { "read", "create", "update" } } } }; // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, null); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.RequestSubmitted); }
public async Task When_Does_Not_have_Permission_To_Access_To_Scope_Then_NotAuthorized_Is_Returned() { var ticket = new TicketLineParameter("client_id") { Scopes = new[] { "read", "create", "update" } }; var authorizationPolicy = new[] { new PolicyRule { Scopes = new[] { "read" } } }; var result = await _authorizationPolicy.Execute( ticket, UmaConstants.IdTokenType, null, CancellationToken.None, authorizationPolicy) .ConfigureAwait(false); Assert.Equal(AuthorizationPolicyResultKind.NotAuthorized, result.Result); }
public async Task When_Client_Is_Not_Allowed_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter("invalid_client_id") { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { ClientIdsAllowed = new List <string> { "client_id" }, Scopes = new List <string> { "read", "create", "update" } } } }; // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, null); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.NotAuthorized); }
public async Task When_Client_Is_Not_Allowed_Then_NotAuthorized_Is_Returned() { var ticket = new TicketLineParameter("invalid_client_id") { Scopes = new[] { "read", "create", "update" } }; var authorizationPolicy = new PolicyRule { ClientIdsAllowed = new[] { "client_id" }, Scopes = new[] { "read", "create", "update" } }; var result = await _authorizationPolicy.Execute( ticket, "http://openid.net/specs/openid-connect-core-1_0.html#IDToken", new ClaimsPrincipal(new ClaimsIdentity(Array.Empty <Claim>())), CancellationToken.None, authorizationPolicy) .ConfigureAwait(false); Assert.Equal(AuthorizationPolicyResultKind.NotAuthorized, result.Result); }
public async Task When_Claims_Are_Not_Correct_Then_NotAuthorized_Is_Returned() { const string configurationUrl = "http://localhost/configuration"; var ticket = new TicketLineParameter("client_id") { Scopes = new[] { "read", "create", "update" } }; var authorizationPolicy = new[] { new PolicyRule { ClientIdsAllowed = new[] { "client_id" }, Scopes = new[] { "read", "create", "update" }, Claims = new[] { new ClaimData { Type = "name", Value = "name" }, new ClaimData { Type = "email", Value = "email" } }, OpenIdProvider = configurationUrl } }; var result = await _authorizationPolicy.Execute( ticket, "http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken", new ClaimsPrincipal(new ClaimsIdentity(Array.Empty <Claim>())), CancellationToken.None, authorizationPolicy) .ConfigureAwait(false); Assert.Equal(AuthorizationPolicyResultKind.NeedInfo, result.Result); }
public Task <AuthorizationPolicyResult> Execute( TicketLineParameter ticketLineParameter, string?claimTokenFormat, ClaimsPrincipal requester, CancellationToken cancellationToken, params PolicyRule[] authorizationPolicy) { cancellationToken.ThrowIfCancellationRequested(); if (authorizationPolicy.Length == 0) { return(Task.FromResult(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.NotAuthorized, requester))); } if (claimTokenFormat != UmaConstants.IdTokenType) { return(GetNeedInfoResult(authorizationPolicy[0].Claims, requester, authorizationPolicy[0].OpenIdProvider ?? string.Empty)); } AuthorizationPolicyResult?result = null; foreach (var rule in authorizationPolicy) { cancellationToken.ThrowIfCancellationRequested(); result = ExecuteAuthorizationPolicyRule( ticketLineParameter, rule, requester, cancellationToken); if (result.Result == AuthorizationPolicyResultKind.Authorized) { break; } } return(Task.FromResult(result !)); }
public async Task When_There_Is_No_Access_Token_Passed_Then_NeedInfo_Is_Returned() { const string configurationUrl = "http://localhost/configuration"; var ticket = new TicketLineParameter("client_id") { Scopes = new[] { "read", "create", "update" } }; var authorizationPolicy = new[] { new PolicyRule { ClientIdsAllowed = new[] { "client_id" }, Scopes = new[] { "read", "create", "update" }, Claims = new[] { new ClaimData { Type = "name", Value = "" }, new ClaimData { Type = "email", Value = "" } }, OpenIdProvider = configurationUrl } }; var result = await _authorizationPolicy.Execute( ticket, "bad_format", new ClaimsPrincipal(new ClaimsIdentity(Array.Empty <Claim>())), CancellationToken.None, authorizationPolicy) .ConfigureAwait(false); Assert.Equal(AuthorizationPolicyResultKind.NeedInfo, result.Result); var errorDetails = (Dictionary <string, object>)result.ErrorDetails; Assert.True(errorDetails.ContainsKey("requesting_party_claims")); var requestingPartyClaims = (Dictionary <string, object>)errorDetails["requesting_party_claims"]; Assert.True(requestingPartyClaims.ContainsKey("required_claims")); Assert.True(requestingPartyClaims.ContainsKey("redirect_user")); var requiredClaims = (List <Dictionary <string, string> >)requestingPartyClaims["required_claims"]; Assert.Contains( requiredClaims, r => r.Any(kv => kv.Key == "name" && kv.Value == "name")); Assert.Contains( requiredClaims, r => r.Any(kv => kv.Key == "friendly_name" && kv.Value == "name")); Assert.Contains( requiredClaims, r => r.Any(kv => kv.Key == "name" && kv.Value == "email")); Assert.Contains( requiredClaims, r => r.Any(kv => kv.Key == "friendly_name" && kv.Value == "email")); }
public async Task When_ResourceOwnerConsent_Is_Required_Then_RequestSubmitted_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read" } }; var authorizationPolicies = new List <Policy> { new Policy { Scopes = new List <string> { "read" }, Claims = new List <Claim> { new Claim { Type = "name", Value = "name" } } } }; _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(new JwsPayload { { "sub", "subject" }, { "name", "bad_name" } })); var claimTokenParameter = new ClaimTokenParameter { Format = "http://openid.net/specs/openid-connect-core-1_0.html#IDToken", Token = "token" }; _pendingRequestRepositorySub.Setup(v => v.Get(It.IsAny <string>(), It.IsAny <string>())).Returns(() => { IEnumerable <PendingRequest> r = new List <PendingRequest>(); return(Task.FromResult(r)); }); // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies, AcceptPendingRequest = true }, ticket, claimTokenParameter); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.True(error.Type == AuthorizationPolicyResultEnum.RequestSubmitted); }
public async Task When_There_Is_No_Access_Token_Passed_Then_NeedInfo_Is_Returned() { // ARRANGE const string configurationUrl = "http://localhost/configuration"; InitializeFakeObjects(); var ticket = new TicketLineParameter("client_id") { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { ClientIdsAllowed = new List <string> { "client_id" }, Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "name" }, new Claim { Type = "email" } }, OpenIdProvider = configurationUrl } } }; var claimTokenParameter = new ClaimTokenParameter { Format = "bad_format", Token = "token" }; // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, claimTokenParameter); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.NeedInfo); var errorDetails = result.ErrorDetails as Dictionary <string, object>; Assert.NotNull(errorDetails); Assert.True(errorDetails.ContainsKey(Constants.ErrorDetailNames.RequestingPartyClaims)); var requestingPartyClaims = errorDetails[Constants.ErrorDetailNames.RequestingPartyClaims] as Dictionary <string, object>; Assert.NotNull(requestingPartyClaims); Assert.True(requestingPartyClaims.ContainsKey(Constants.ErrorDetailNames.RequiredClaims)); Assert.True(requestingPartyClaims.ContainsKey(Constants.ErrorDetailNames.RedirectUser)); var requiredClaims = requestingPartyClaims[Constants.ErrorDetailNames.RequiredClaims] as List <Dictionary <string, string> >; Assert.NotNull(requiredClaims); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimName && kv.Value == "name"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimFriendlyName && kv.Value == "name"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimName && kv.Value == "email"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimFriendlyName && kv.Value == "email"))); }
public async Task When_Claims_Are_Not_Corred_Then_NotAuthorized_Is_Returned() { // ARRANGE const string configurationUrl = "http://localhost/configuration"; InitializeFakeObjects(); var ticket = new TicketLineParameter("client_id") { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { ClientIdsAllowed = new List <string> { "client_id" }, Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "name", Value = "name" }, new Claim { Type = "email", Value = "email" } }, OpenIdProvider = configurationUrl } } }; var claimTokenParameter = new ClaimTokenParameter { Format = "http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken", Token = "token" }; _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>(), It.IsAny <PolicyRule>())) .Returns(Task.FromResult(new JwsPayload { { "name", "bad_name" } })); // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, claimTokenParameter); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.NeedInfo); }
public async Task When_There_Is_No_Access_Token_Passed_Then_NeedInfo_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicies = new List <Policy> { new Policy { Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "name" }, new Claim { Type = "email" } } } }; var claimTokenParameter = new ClaimTokenParameter { Format = "bad_format", Token = "token" }; // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies }, ticket, claimTokenParameter); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.True(error.Type == AuthorizationPolicyResultEnum.NeedInfo); var errorDetails = error.ErrorDetails as Dictionary <string, object>; Assert.NotNull(errorDetails); Assert.True(errorDetails.ContainsKey(Constants.ErrorDetailNames.RequestingPartyClaims)); var requestingPartyClaims = errorDetails[Constants.ErrorDetailNames.RequestingPartyClaims] as Dictionary <string, object>; Assert.NotNull(requestingPartyClaims); Assert.True(requestingPartyClaims.ContainsKey(Constants.ErrorDetailNames.RequiredClaims)); Assert.True(requestingPartyClaims.ContainsKey(Constants.ErrorDetailNames.RedirectUser)); var requiredClaims = requestingPartyClaims[Constants.ErrorDetailNames.RequiredClaims] as List <Dictionary <string, string> >; Assert.NotNull(requiredClaims); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimName && kv.Value == "name"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimFriendlyName && kv.Value == "name"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimName && kv.Value == "email"))); Assert.True(requiredClaims.Any(r => r.Any(kv => kv.Key == Constants.ErrorDetailNames.ClaimFriendlyName && kv.Value == "email"))); }
public async Task <AuthorizationPolicyResult> IsAuthorized( Ticket validTicket, Client client, ClaimTokenParameter claimTokenParameter, CancellationToken cancellationToken) { if (validTicket.Lines.Length == 0) { throw new ArgumentException(nameof(validTicket.Lines)); } var handler = new JwtSecurityTokenHandler(); var validationParameters = await client.CreateValidationParameters(_jwksStore, cancellationToken : cancellationToken).ConfigureAwait(false); var requester = handler.ValidateToken(claimTokenParameter.Token, validationParameters, out _); var resourceIds = validTicket.Lines.Select(l => l.ResourceSetId).ToArray(); var resources = await _resourceSetRepository.Get(cancellationToken, resourceIds).ConfigureAwait(false); if (resources.Length == 0 || resources.Length != resourceIds.Length) { return(new AuthorizationPolicyResult(AuthorizationPolicyResultKind.NotAuthorized, requester)); } AuthorizationPolicyResult?validationResult = null; foreach (var ticketLine in validTicket.Lines) { var ticketLineParameter = new TicketLineParameter( client.ClientId, ticketLine.Scopes, validTicket.IsAuthorizedByRo); var resource = resources.First(r => r.Id == ticketLine.ResourceSetId); validationResult = await Validate( ticketLineParameter, resource, claimTokenParameter.Format, requester, cancellationToken) .ConfigureAwait(false); switch (validationResult.Result) { case AuthorizationPolicyResultKind.RequestSubmitted: await _eventPublisher.Publish( new AuthorizationRequestSubmitted( Id.Create(), validTicket.Id, client.ClientId, requester.Claims.Select(claim => new ClaimData { Type = claim.Type, Value = claim.Value }), DateTimeOffset.UtcNow)) .ConfigureAwait(false); return(validationResult); case AuthorizationPolicyResultKind.Authorized: break; case AuthorizationPolicyResultKind.NotAuthorized: case AuthorizationPolicyResultKind.NeedInfo: default: { await _eventPublisher.Publish( new AuthorizationPolicyNotAuthorized( Id.Create(), validTicket.Id, DateTimeOffset.UtcNow)) .ConfigureAwait(false); return(validationResult); } } } return(validationResult !); }