GetProfileDataAsync() public method

public GetProfileDataAsync ( ProfileDataRequestContext, context ) : Task,
context ProfileDataRequestContext,
return Task,
        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            await _delegate.GetProfileDataAsync(context);

            foreach (var plugin in _profileServiceDelegates)
            {
                await plugin.GetProfileDataAsync(context);
            }
        }
Ejemplo n.º 2
0
        public async Task GetProfileDataAsync_should_get_add_act_claim()
        {
            var services = new ServiceCollection()
                           .AddLogging()
                           .AddDbContext <IdentityDbContext>(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString()));

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores <IdentityDbContext>();

            var provider = services.BuildServiceProvider();
            var manager  = provider.GetRequiredService <UserManager <IdentityUser> >();

            var user = new IdentityUser
            {
                UserName = "******"
            };
            await manager.CreateAsync(user);

            var context = new ProfileDataRequestContext(new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
            {
                new Claim(JwtClaimTypes.Subject, "not_found"),
                new Claim("amr", OidcConstants.GrantTypes.TokenExchange),
                new Claim(JwtClaimTypes.Actor, "api1")
            })),
                                                        new Client(), "test",
                                                        new string[] { "test" })
            {
                RequestedResources = new ResourceValidationResult
                {
                    Resources = new Resources
                    {
                        ApiResources = new List <ApiResource>
                        {
                            new ApiResource
                            {
                                Properties = new Dictionary <string, string>
                                {
                                    [ProfileServiceProperties.ClaimProviderTypeKey]         = typeof(ClaimsProvider).FullName,
                                    [ProfileServiceProperties.ClaimProviderAssemblyPathKey] = $"{typeof(ClaimsProvider).Assembly.GetName().Name}.dll"
                                }
                            }
                        }
                    }
                }
            };

            var sut = new ProfileService <IdentityUser>(provider.GetRequiredService <UserManager <IdentityUser> >(),
                                                        provider.GetRequiredService <IUserClaimsPrincipalFactory <IdentityUser> >(),
                                                        provider.GetService <IEnumerable <IProvideClaims> >(),
                                                        provider.GetRequiredService <ILogger <ProfileService <IdentityUser> > >());

            await sut.GetProfileDataAsync(context);

            Assert.Contains(context.IssuedClaims, c => c.Type == JwtClaimTypes.Actor);
        }
Ejemplo n.º 3
0
        public async Task GetProfileDataAsync_should_resolve_provider_type_from_di()
        {
            var services = new ServiceCollection()
                           .AddLogging()
                           .AddTransient <IProvideClaims, ClaimsProvider>()
                           .AddDbContext <IdentityDbContext>(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString()));

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores <IdentityDbContext>();
            var provider = services.BuildServiceProvider();
            var manager  = provider.GetRequiredService <UserManager <IdentityUser> >();

            var user = new IdentityUser
            {
                UserName = "******"
            };
            await manager.CreateAsync(user);

            var context = new ProfileDataRequestContext(new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim(JwtClaimTypes.Subject, user.Id) })),
                                                        new Client(), "test",
                                                        new string[] { "test" })
            {
                RequestedResources = new ResourceValidationResult
                {
                    Resources = new Resources
                    {
                        IdentityResources = new List <IdentityResource>
                        {
                            new IdentityResource
                            {
                                Properties = new Dictionary <string, string>
                                {
                                    [ProfileServiceProperties.ClaimProviderTypeKey] = typeof(ClaimsProvider).FullName
                                }
                            }
                        }
                    }
                }
            };

            var sut = new ProfileService <IdentityUser>(provider.GetRequiredService <UserManager <IdentityUser> >(),
                                                        provider.GetRequiredService <IUserClaimsPrincipalFactory <IdentityUser> >(),
                                                        provider.GetService <IEnumerable <IProvideClaims> >(),
                                                        provider.GetRequiredService <ILogger <ProfileService <IdentityUser> > >());

            await sut.GetProfileDataAsync(context);

            Assert.Contains(context.IssuedClaims, c => c.Type == "test");
        }
        public async Task GetProfileDataAsync_withGivenArgument_ReturnExpectedResult_TestSuite(string jobTitle, string fullName, string configuration, int expectedValue)
        {
            // Arrange
            _user = new ApplicationUser()
            {
                JobTitle      = jobTitle,
                FullName      = fullName,
                Configuration = configuration
            };

            _userManagerMock.Setup(x => x.FindByIdAsync(It.IsAny <string>())).ReturnsAsync(_user);

            var identity = new List <ClaimsIdentity>()
            {
                new ClaimsIdentity(new List <Claim>()
                {
                    new Claim("sub", "1")
                })
            };
            var claimsPrincipal = new ClaimsPrincipal(identity);

            _userClaimFactoryMock.Setup(x => x.CreateAsync(It.IsAny <ApplicationUser>())).ReturnsAsync(claimsPrincipal);

            var context = new ProfileDataRequestContext();

            context.Subject             = claimsPrincipal;
            context.RequestedClaimTypes = new List <string>()
            {
                "sub"
            };

            var profileService = new ProfileService(_userManagerMock.Object, _userClaimFactoryMock.Object);

            // Act
            await profileService.GetProfileDataAsync(context);

            // Assert
            Assert.AreEqual(expectedValue, context.IssuedClaims.Count);
        }
Ejemplo n.º 5
0
        public async Task <IEndpointResult> ProcessAsync(HttpContext httpContext)
        {
            Logger.LogInformation($"[{nameof(InitRegistrationEndpoint)}] Started processing trusted device registration initiation endpoint.");
            var isPostRequest = HttpMethods.IsPost(httpContext.Request.Method);
            var isApplicationFormContentType = httpContext.Request.HasApplicationFormContentType();

            // Validate HTTP request type and method.
            if (!isPostRequest || !isApplicationFormContentType)
            {
                return(Error(OidcConstants.TokenErrors.InvalidRequest, "Request must be of type 'POST' and have a Content-Type equal to 'application/x-www-form-urlencoded'."));
            }
            // Ensure that a valid 'Authorization' header exists.
            var tokenUsageResult = await Token.Validate(httpContext);

            if (!tokenUsageResult.TokenFound)
            {
                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, "No access token is present in the request."));
            }
            // Validate request data and access token.
            var parameters = (await httpContext.Request.ReadFormAsync()).AsNameValueCollection();
            var requestValidationResult = await Request.Validate(parameters, tokenUsageResult.Token);

            if (requestValidationResult.IsError)
            {
                return(Error(requestValidationResult.Error, requestValidationResult.ErrorDescription));
            }
            // Ensure device is not already registered or belongs to any other user.
            var existingDevice = await UserDeviceStore.GetByDeviceId(requestValidationResult.DeviceId);

            var isNewDeviceOrOwnedByUser = existingDevice == null || existingDevice.UserId.Equals(requestValidationResult.UserId, StringComparison.OrdinalIgnoreCase);

            if (!isNewDeviceOrOwnedByUser)
            {
                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, "Device does not belong to the this user."));
            }
            // Ensure that the principal has declared a phone number which is also confirmed.
            // We will get these 2 claims by retrieving the identity resources from the store (using the requested scopes existing in the access token) and then calling the profile service.
            // This will help us make sure that the 'phone' scope was requested and finally allowed in the token endpoint.
            var identityResources = await ResourceStore.FindEnabledIdentityResourcesByScopeAsync(requestValidationResult.RequestedScopes);

            var resources          = new Resources(identityResources, Enumerable.Empty <ApiResource>(), Enumerable.Empty <ApiScope>());
            var validatedResources = new ResourceValidationResult(resources);

            if (!validatedResources.Succeeded)
            {
                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, "Identity resources could be validated."));
            }
            var requestedClaimTypes       = resources.IdentityResources.SelectMany(x => x.UserClaims).Distinct();
            var profileDataRequestContext = new ProfileDataRequestContext(requestValidationResult.Principal, requestValidationResult.Client, IdentityServerConstants.ProfileDataCallers.UserInfoEndpoint, requestedClaimTypes)
            {
                RequestedResources = validatedResources
            };
            await ProfileService.GetProfileDataAsync(profileDataRequestContext);

            var profileClaims            = profileDataRequestContext.IssuedClaims;
            var phoneNumberClaim         = profileClaims.FirstOrDefault(x => x.Type == JwtClaimTypes.PhoneNumber);
            var phoneNumberVerifiedClaim = profileClaims.FirstOrDefault(x => x.Type == JwtClaimTypes.PhoneNumberVerified);

            if (string.IsNullOrWhiteSpace(phoneNumberClaim?.Value) || phoneNumberVerifiedClaim == null || (bool.TryParse(phoneNumberVerifiedClaim.Value, out var phoneNumberVerified) && !phoneNumberVerified))
            {
                return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken, "User does not have a phone number or the phone number is not verified."));
            }
            var otpAuthenticatedValue = profileClaims.FirstOrDefault(x => x.Type == BasicClaimTypes.OtpAuthenticated)?.Value;
            var otpAuthenticated      = !string.IsNullOrWhiteSpace(otpAuthenticatedValue) && bool.Parse(otpAuthenticatedValue);

            if (!otpAuthenticated)
            {
                // Send OTP code.
                void messageBuilder(TotpMessageBuilder message)
                {
                    var builder = message.UsePrincipal(requestValidationResult.Principal).WithMessage(IdentityMessageDescriber.DeviceRegistrationCodeMessage(existingDevice?.Name, requestValidationResult.InteractionMode));

                    if (requestValidationResult.DeliveryChannel == TotpDeliveryChannel.Sms)
                    {
                        builder.UsingSms();
                    }
                    else
                    {
                        builder.UsingViber();
                    }
                    builder.WithPurpose(Constants.TrustedDeviceOtpPurpose(requestValidationResult.UserId, requestValidationResult.DeviceId));
                }

                var totpResult = await TotpService.Send(messageBuilder);

                if (!totpResult.Success)
                {
                    return(Error(totpResult.Error));
                }
            }
            // Create endpoint response.
            var response = await Response.Generate(requestValidationResult);

            Logger.LogInformation($"[{nameof(InitRegistrationEndpoint)}] Trusted device registration initiation endpoint success.");
            return(new InitRegistrationResult(response));
        }