public void ProcessAsync_should_throw_if_incorrect_sub_issued_by_profile_service() { _identityResources.Add(new IdentityResource("id1", new[] { "foo" })); _identityResources.Add(new IdentityResource("id2", new[] { "bar" })); _mockProfileService.ProfileClaims = new[] { new Claim("sub", "fred") }; var result = new UserInfoRequestValidationResult { Subject = _user, TokenValidationResult = new TokenValidationResult { Claims = new List <Claim> { { new Claim("scope", "id1") }, { new Claim("scope", "id2") }, { new Claim("scope", "id3") } }, Client = _client } }; Func <Task> act = () => _subject.ProcessAsync(result); act.Should().Throw <InvalidOperationException>() .And.Message.Should().Contain("subject"); }
public async Task ProcessAsync_should_call_profile_service_with_requested_claim_types() { _identityResources.Add(new IdentityResource("id1", new[] { "foo" })); _identityResources.Add(new IdentityResource("id2", new[] { "bar" })); var result = new UserInfoRequestValidationResult { Subject = _user, TokenValidationResult = new TokenValidationResult { Claims = new List <Claim> { { new Claim("scope", "id1") }, { new Claim("scope", "id2") }, { new Claim("scope", "id3") } }, Client = _client } }; var claims = await _subject.ProcessAsync(result); _mockProfileService.GetProfileWasCalled.Should().BeTrue(); _mockProfileService.ProfileContext.RequestedClaimTypes.Should().BeEquivalentTo(new[] { "foo", "bar" }); }
public async Task ProcessAsync_should_return_sub_from_user() { _identityResources.Add(new IdentityResource("id1", new[] { "foo" })); _identityResources.Add(new IdentityResource("id2", new[] { "bar" })); var result = new UserInfoRequestValidationResult { Subject = _user, TokenValidationResult = new TokenValidationResult { Claims = new List <Claim> { { new Claim("scope", "id1") }, { new Claim("scope", "id2") }, { new Claim("scope", "id3") } }, Client = _client } }; var claims = await _subject.ProcessAsync(result); claims.Should().ContainKey("sub"); claims["sub"].Should().Be("bob"); }
public async Task ProcessAsync_should_return_claims_issued_by_profile_service() { _identityResources.Add(new IdentityResource("id1", new[] { "foo" })); _identityResources.Add(new IdentityResource("id2", new[] { "bar" })); _mockProfileService.ProfileClaims = new[] { new Claim("email", "*****@*****.**"), new Claim("name", "fred jones") }; var result = new UserInfoRequestValidationResult { Subject = _user, TokenValidationResult = new TokenValidationResult { Claims = new List <Claim> { { new Claim("scope", "id1") }, { new Claim("scope", "id2") }, { new Claim("scope", "id3") } }, Client = _client } }; var claims = await _subject.ProcessAsync(result); claims.Should().ContainKey("email"); claims["email"].Should().Be("*****@*****.**"); claims.Should().ContainKey("name"); claims["name"].Should().Be("fred jones"); }
/// <summary> /// Creates the response. /// </summary> /// <param name="validationResult">The userinfo request validation result.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">Profile service returned incorrect subject value</exception> public virtual async Task <Dictionary <string, object> > ProcessAsync(UserInfoRequestValidationResult validationResult) { using var activity = Tracing.BasicActivitySource.StartActivity("UserInfoResponseGenerator.Process"); Logger.LogDebug("Creating userinfo response"); // extract scopes and turn into requested claim types var scopes = validationResult.TokenValidationResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope).Select(c => c.Value); var validatedResources = await GetRequestedResourcesAsync(scopes); var requestedClaimTypes = await GetRequestedClaimTypesAsync(validatedResources); Logger.LogDebug("Requested claim types: {claimTypes}", requestedClaimTypes.ToSpaceSeparatedString()); // call profile service var context = new ProfileDataRequestContext( validationResult.Subject, validationResult.TokenValidationResult.Client, IdentityServerConstants.ProfileDataCallers.UserInfoEndpoint, requestedClaimTypes); context.RequestedResources = validatedResources; await Profile.GetProfileDataAsync(context); var profileClaims = context.IssuedClaims; // construct outgoing claims var outgoingClaims = new List <Claim>(); if (profileClaims == null) { Logger.LogInformation("Profile service returned no claims (null)"); } else { outgoingClaims.AddRange(profileClaims); Logger.LogInformation("Profile service returned the following claim types: {types}", profileClaims.Select(c => c.Type).ToSpaceSeparatedString()); } var subClaim = outgoingClaims.SingleOrDefault(x => x.Type == JwtClaimTypes.Subject); if (subClaim == null) { outgoingClaims.Add(new Claim(JwtClaimTypes.Subject, validationResult.Subject.GetSubjectId())); } else if (subClaim.Value != validationResult.Subject.GetSubjectId()) { Logger.LogError("Profile service returned incorrect subject value: {sub}", subClaim); throw new InvalidOperationException("Profile service returned incorrect subject value"); } return(outgoingClaims.ToClaimsDictionary()); }
public async Task ProcessAsync_should_return_claims_issued_by_profile_service() { _identityResources.Add(new IdentityResource("id1", new[] { "foo" })); _identityResources.Add(new IdentityResource("id2", new[] { "bar" })); var address = new { street_address = "One Hacker Way", locality = "Heidelberg", postal_code = 69118, country = "Germany" }; _mockProfileService.ProfileClaims = new[] { new Claim("email", "*****@*****.**"), new Claim("name", "fred jones"), new Claim("address", @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServerConstants.ClaimValueTypes.Json), new Claim("address2", JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json) }; var result = new UserInfoRequestValidationResult { Subject = _user, TokenValidationResult = new TokenValidationResult { Claims = new List <Claim> { { new Claim("scope", "id1") }, { new Claim("scope", "id2") }, { new Claim("scope", "id3") } }, Client = _client } }; var claims = await _subject.ProcessAsync(result); claims.Should().ContainKey("email"); claims["email"].Should().Be("*****@*****.**"); claims.Should().ContainKey("name"); claims["name"].Should().Be("fred jones"); // this will be treated as a string because this is not valid JSON from the System.Text library point of view claims.Should().ContainKey("address"); claims["address"].Should().Be("{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }"); // this is a JsonElement claims.Should().ContainKey("address2"); claims["address2"].ToString().Should().Be("{\"street_address\":\"One Hacker Way\",\"locality\":\"Heidelberg\",\"postal_code\":69118,\"country\":\"Germany\"}"); }
public override Task <Dictionary <string, object> > ProcessAsync(UserInfoRequestValidationResult validationResult) { return(base.ProcessAsync(validationResult)); }