public async Task OnValidateIdentityRejectsWhenValidateSecurityStampFails()
        {
            var user = new TestUser("test");
            var userManager = MockHelpers.MockUserManager<TestUser>();
            var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
            var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero };
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var httpContext = new Mock<HttpContext>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
            var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
                contextAccessor.Object, claimsManager.Object, options.Object, null);
            signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>(), user.Id)).ReturnsAsync(null).Verifiable();
            var services = new ServiceCollection();
            services.AddInstance(options.Object);
            services.AddInstance(signInManager.Object);
            services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>());
            httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
            var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme);
            id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));

            var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
                new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
                IdentityOptions.ApplicationCookieAuthenticationScheme);
            var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
            Assert.NotNull(context.Properties);
            Assert.NotNull(context.Options);
            Assert.NotNull(context.Principal);
            await SecurityStampValidator.ValidatePrincipalAsync(context);
            Assert.Null(context.Principal);
            signInManager.VerifyAll();
        }
 public async Task OnValidatePrincipalThrowsWithEmptyServiceCollection()
 {
     var scheme = new IdentityOptions().Cookies.ApplicationCookieAuthenticationScheme;
     var httpContext = new Mock<HttpContext>();
     httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider());
     var id = new ClaimsPrincipal(new ClaimsIdentity(scheme));
     var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, scheme);
     var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
     var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => SecurityStampValidator.ValidatePrincipalAsync(context));
     Assert.True(ex.Message.Contains("No service for type 'Microsoft.Extensions.OptionsModel.IOptions"));
 }
 public async Task CreateIdentityNullChecks()
 {
     var userManager = MockHelpers.MockUserManager<TestUser>().Object;
     var roleManager = MockHelpers.MockRoleManager<TestRole>().Object;
     var options = new Mock<IOptions<IdentityOptions>>();
     Assert.Throws<ArgumentNullException>("optionsAccessor",
         () => new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager, roleManager, options.Object));
     var identityOptions = new IdentityOptions();
     options.Setup(a => a.Options).Returns(identityOptions);
     var factory = new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager, roleManager, options.Object);
     await Assert.ThrowsAsync<ArgumentNullException>("user",
         async () => await factory.CreateAsync(null));
 }
예제 #4
0
        public JwtTokenResult RefreshAccessToken(
            string accessToken,
            string refreshToken,
            IEnumerable <string> customClaimsType)
        {
            var result = ValidateRefreshToken(refreshToken);

            if (result.result != JwtTokenResult.TokenResult.Ok)
            {
                return(new JwtTokenResult(result.result));
            }

            Claim[] accessClaims = null;
            try
            {
                accessClaims = new JwtSecurityTokenHandler()
                               .ReadJwtToken(accessToken)
                               .Claims.ToArray();
            }
            catch
            {
                return(JwtTokenResult.AccessInvalid());
            }

            var identityOptions = new IdentityOptions();
            var refreshId       = result.claims
                                  .FirstOrDefault(x => x.Type
                                                  .Equals(JwtRegisteredClaimNames.Sub))
                                  .Value;

            var accessId = accessClaims
                           .FirstOrDefault(x => x.Type
                                           .Equals(JwtRegisteredClaimNames.Sub))
                           .Value;

            if (!refreshId.Equals(accessId))
            {
                return(JwtTokenResult.Mismatch());
            }

            var refreshJti = result.claims
                             .FirstOrDefault(x => x.Type
                                             .Equals(JwtRegisteredClaimNames.Jti))
                             .Value;
            var accessName = accessClaims
                             .FirstOrDefault(x => x.Type
                                             .Equals(identityOptions.ClaimsIdentity.UserNameClaimType))
                             .Value;
            var roles = accessClaims
                        .Where(x => x.Type
                               .Equals(ClaimTypes.Role));

            List <Claim> claims = null;

            if (customClaimsType != null)
            {
                var customClaims = accessClaims
                                   .Where(claim => customClaimsType.Contains(claim.Type))
                                   .ToArray();
                if (customClaims != null && customClaims.Length > 0)
                {
                    claims = GetAccessClaims(accessId, accessName, roles, customClaims);
                }
                else
                {
                    claims = GetAccessClaims(accessId, accessName, roles);
                }
            }
            else
            {
                claims = GetAccessClaims(accessId, accessName, roles);
            }

            var newAccessToken = CreateAccessToken(claims);

            if (result.update)
            {
                var newRefreshToken = GetRefreshToken(accessId, accessName);

                return(JwtTokenResult.Ok(new TokenModel
                                         (
                                             newAccessToken,
                                             newRefreshToken
                                         ),
                                         accessId,
                                         accessClaims));
            }

            return(JwtTokenResult.Ok(
                       new TokenModel(newAccessToken, (null, default, refreshJti)),
 public ExampleUserPrincipalFactory(IOptions <IdentityOptions> optionsAccessor)
 {
     _options = optionsAccessor?.Value ?? new IdentityOptions();
 }
예제 #6
0
        public (Mock <SignInManager <User> >, Mock <UserManager <User> >, Mock <IEmailConfirmation>, AuthService) CreateAuthService()
        {
            Mock <IUserPasswordStore <User> > userPasswordStore = new Mock <IUserPasswordStore <User> >();

            userPasswordStore.Setup(s => s.CreateAsync(It.IsAny <User>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(IdentityResult.Success));

            var options   = new Mock <IOptions <IdentityOptions> >();
            var idOptions = new IdentityOptions();

            idOptions.SignIn.RequireConfirmedEmail    = true;
            idOptions.Password.RequireDigit           = true;
            idOptions.Password.RequiredLength         = 8;
            idOptions.Password.RequireUppercase       = false;
            idOptions.User.RequireUniqueEmail         = true;
            idOptions.Password.RequireNonAlphanumeric = false;
            idOptions.Lockout.MaxFailedAccessAttempts = 5;
            idOptions.Lockout.DefaultLockoutTimeSpan  = TimeSpan.FromMinutes(15);

            options.Setup(o => o.Value).Returns(idOptions);
            var userValidators             = new List <IUserValidator <User> >();
            UserValidator <User> validator = new UserValidator <User>();

            userValidators.Add(validator);

            var passValidator = new PasswordValidator <User>();
            var pwdValidators = new List <IPasswordValidator <User> >();

            pwdValidators.Add(passValidator);

            var userStore = new Mock <IUserStore <User> >();

            userStore.Setup(s => s.CreateAsync(It.IsAny <User>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(IdentityResult.Success));

            var mockUserManager = new Mock <UserManager <User> >(userStore.Object,
                                                                 options.Object, new PasswordHasher <User>(),
                                                                 userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
                                                                 new IdentityErrorDescriber(), null,
                                                                 new Mock <ILogger <UserManager <User> > >().Object);

            mockUserManager
            .Setup(s => s.CreateAsync(It.IsAny <User>(), It.IsAny <string>()))
            .Returns(Task.FromResult(IdentityResult.Success));

            var _contextAccessor      = new Mock <IHttpContextAccessor>();
            var _userPrincipalFactory = new Mock <IUserClaimsPrincipalFactory <User> >();
            var mockSignInManager     = new Mock <SignInManager <User> >(mockUserManager.Object,
                                                                         _contextAccessor.Object, _userPrincipalFactory.Object, null, null, null, null);

            Mock <IRepositoryWrapper> mockRepositoryWrapper = new Mock <IRepositoryWrapper>();
            Mock <IEmailConfirmation> mockEmailConfirmation = new Mock <IEmailConfirmation>();
            Mock <IMapper>            mockMapper            = new Mock <IMapper>();

            mockMapper
            .Setup(s => s.Map <UserDTO, User>(It.IsAny <UserDTO>()))
            .Returns(GetTestUserWithEmailsSendedTime());

            AuthService AuthService = new AuthService(mockUserManager.Object, mockSignInManager.Object,
                                                      mockEmailConfirmation.Object, mockMapper.Object, null, null);

            return(mockSignInManager, mockUserManager, mockEmailConfirmation, AuthService);
        }
예제 #7
0
        public async Task PasswordSignInReturnsLockedOutWhenLockedOut()
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
            manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();

            var context = new Mock<HttpContext>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Value).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger.Object);

            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);

            // Assert
            Assert.False(result.Succeeded);
            Assert.True(result.IsLockedOut);
            Assert.True(logStore.ToString().Contains($"User {user.Id} is currently locked out."));
            manager.Verify();
        }
예제 #8
0
                public void DefaultValueCookieHttpOnlyProperty_EqualsTrue()
                {
                    var options = new IdentityOptions();

                    Assert.True(options.Cookie.Cookie.HttpOnly);
                }
예제 #9
0
        public async Task CanTwoFactorSignIn(bool isPersistent, bool supportsLockout, bool externalLogin, bool rememberClient)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            var provider = "twofactorprovider";
            var code = "123456";
            manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable();
            if (supportsLockout)
            {
                manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
                manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
            }
            manager.Setup(m => m.VerifyTwoFactorTokenAsync(user, provider, code)).ReturnsAsync(true).Verifiable();
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            var twoFactorInfo = new SignInManager<TestUser>.TwoFactorAuthenticationInfo { UserId = user.Id };
            var loginProvider = "loginprovider";
            var id = SignInManager<TestUser>.StoreTwoFactorInfo(user.Id, externalLogin ? loginProvider : null);
            var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription());
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
            if (externalLogin)
            {
                response.Setup(r => r.SignIn(
                    IdentityOptions.ApplicationCookieAuthenticationScheme,
                    It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider
                        && i.FindFirstValue(ClaimTypes.NameIdentifier) == user.Id),
                    It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
                response.Setup(r => r.SignOut(IdentityOptions.ExternalCookieAuthenticationScheme)).Verifiable();
            }
            else
            {
                SetupSignIn(response, user.Id);
            }
            if (rememberClient)
            {
                response.Setup(r => r.SignIn(
                    IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme,
                    It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
                        && i.Identities.First().AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType),
                    It.Is<AuthenticationProperties>(v => v.IsPersistent == true))).Verifiable();
            }
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            context.Setup(c => c.AuthenticateAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(authResult).Verifiable();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, null);
            helper.Logger = logger.Object;
            string expectedScope = string.Format("{0} for {1}: {2}", "TwoFactorSignInAsync", "user", user.Id);
            string expectedLog = string.Format("{0} : {1}", "TwoFactorSignInAsync", "Succeeded");

            // Act
            var result = await helper.TwoFactorSignInAsync(provider, code, isPersistent, rememberClient);

            // Assert
            Assert.True(result.Succeeded);
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedLog));
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedScope));
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
        }
예제 #10
0
        public async Task PasswordSignInFailsWithWrongPassword()
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
            manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
            manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
            var context = new Mock<HttpContext>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);
            helper.Logger = logger.Object;
            string expectedScope = string.Format("{0} for {1}: {2}", "PasswordSignInAsync", "user", user.Id);
            string expectedLog = string.Format("{0} : {1}", "PasswordSignInAsync", "Failed");
            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);

            // Assert
            Assert.False(result.Succeeded);
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedLog));
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedScope));
            manager.Verify();
            context.Verify();
            contextAccessor.Verify();
        }
예제 #11
0
 public AuthTokensService(IdentityOptions options)
 => _options = options;
예제 #12
0
 public override void Visit(IdentityOptions node) { this.action(node); }
        private static SignInManager <TestUser> SetupSignInManager(UserManager <TestUser> manager, HttpContext context, StringBuilder logStore = null, IdentityOptions identityOptions = null)
        {
            var contextAccessor = new Mock <IHttpContextAccessor>();

            contextAccessor.Setup(a => a.HttpContext).Returns(context);
            var roleManager = MockHelpers.MockRoleManager <TestRole>();

            identityOptions = identityOptions ?? new IdentityOptions();
            var options = new Mock <IOptions <IdentityOptions> >();

            options.Setup(a => a.Value).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory <TestUser, TestRole>(manager, roleManager.Object, options.Object);
            var sm            = new SignInManager <TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null, new Mock <IAuthenticationSchemeProvider>().Object);

            sm.Logger = MockHelpers.MockILogger <SignInManager <TestUser> >(logStore ?? new StringBuilder()).Object;
            return(sm);
        }
예제 #14
0
                public void Get_NotNullByDefault()
                {
                    var options = new IdentityOptions();

                    Assert.NotNull(options.Claims);
                }
예제 #15
0
                public void DefaultValueSlidingExpirationProperty_EqualsTrue()
                {
                    var options = new IdentityOptions();

                    Assert.True(options.Cookie.SlidingExpiration);
                }
예제 #16
0
                public void DefaultValueExpireTimeSpanProperty_Equals7Days()
                {
                    var options = new IdentityOptions();

                    Assert.Equal(TimeSpan.FromDays(7), options.Cookie.ExpireTimeSpan);
                }
예제 #17
0
                public void DefaultValueCookieSecurePolicyProperty_EqualsAlways()
                {
                    var options = new IdentityOptions();

                    Assert.Equal(CookieSecurePolicy.Always, options.Cookie.Cookie.SecurePolicy);
                }
예제 #18
0
        public async Task PasswordSignInRequiresVerification(bool supportsLockout)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable();
            if (supportsLockout)
            {
                manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
            }
            IList<string> providers = new List<string>();
            providers.Add("PhoneNumber");
            manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).Returns(Task.FromResult(providers)).Verifiable();
            manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
            manager.Setup(m => m.GetTwoFactorEnabledAsync(user)).ReturnsAsync(true).Verifiable();
            manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
            if (supportsLockout)
            {
                manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
            }
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            response.Setup(r => r.SignIn(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme,
                It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id),
                It.IsAny<AuthenticationProperties>())).Verifiable();
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object,
                contextAccessor.Object,
                new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object),
                options.Object,
                null);
            helper.Logger = logger.Object;
            string expectedScope = string.Format("{0} for {1}: {2}", "PasswordSignInAsync", "user", user.Id);
            string expectedLog = string.Format("{0} : {1}", "PasswordSignInAsync", "RequiresTwoFactor");

            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);

            // Assert
            Assert.False(result.Succeeded);
            Assert.True(result.RequiresTwoFactor);
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedLog));
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedScope));
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
        }
    public override async Task <IActionResult> OnPostAsync(string action)
    {
        var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);

        if (action == "Cancel")
        {
            if (context == null)
            {
                return(Redirect("~/"));
            }

            await Interaction.GrantConsentAsync(context, new ConsentResponse()
            {
                Error = AuthorizationError.AccessDenied
            });

            return(Redirect(ReturnUrl));
        }

        await CheckLocalLoginAsync();

        ValidateModel();

        await IdentityOptions.SetAsync();

        ExternalProviders = await GetExternalProviders();

        EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);

        await ReplaceEmailToUsernameOfInputIfNeeds();

        var result = await SignInManager.PasswordSignInAsync(
            LoginInput.UserNameOrEmailAddress,
            LoginInput.Password,
            LoginInput.RememberMe,
            true
            );

        await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
        {
            Identity = IdentitySecurityLogIdentityConsts.Identity,
            Action   = result.ToIdentitySecurityLogAction(),
            UserName = LoginInput.UserNameOrEmailAddress,
            ClientId = context?.Client?.ClientId
        });

        if (result.RequiresTwoFactor)
        {
            return(await TwoFactorLoginResultAsync());
        }

        if (result.IsLockedOut)
        {
            Alerts.Warning(L["UserLockedOutMessage"]);
            return(Page());
        }

        if (result.IsNotAllowed)
        {
            Alerts.Warning(L["LoginIsNotAllowed"]);
            return(Page());
        }

        if (!result.Succeeded)
        {
            Alerts.Danger(L["InvalidUserNameOrPassword"]);
            return(Page());
        }

        //TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
        var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
                   await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);

        Debug.Assert(user != null, nameof(user) + " != null");
        await IdentityServerEvents.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName)); //TODO: Use user's name once implemented

        return(RedirectSafely(ReturnUrl, ReturnUrlHash));
    }
예제 #20
0
        public async Task RememberBrowserSkipsTwoFactorVerificationSignIn(bool isPersistent)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.GetTwoFactorEnabledAsync(user)).ReturnsAsync(true).Verifiable();
            IList<string> providers = new List<string>();
            providers.Add("PhoneNumber");
            manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).Returns(Task.FromResult(providers)).Verifiable();
            manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
            manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
            manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
            manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            SetupSignIn(response);
            var id = new ClaimsIdentity(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
            id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
            var authResult = new AuthenticationResult(new ClaimsPrincipal(id), new AuthenticationProperties(), new AuthenticationDescription());
            context.Setup(c => c.AuthenticateAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme)).ReturnsAsync(authResult).Verifiable();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            claimsFactory.Setup(m => m.CreateAsync(user)).ReturnsAsync(new ClaimsPrincipal(new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType))).Verifiable();
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);

            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);

            // Assert
            Assert.True(result.Succeeded);
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
            claimsFactory.Verify();
        }
예제 #21
0
        /// <summary>
        /// This method is callback for external authorizing.
        /// </summary>
        /// <param name="provider">Provider for external authorization.</param>
        /// <returns>JSON Web Token.</returns>
        public async Task <string> ExternalLoginCallBack(string provider)
        {
            var info = await Database.SignInManager.GetExternalLoginInfoAsync();

            if (info == null)
            {
                throw new ValidationException("Error loading external login information");
            }
            string Email      = "";
            var    identifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
            string picture    = "";
            string Name       = info.Principal.Identity.Name;

            if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
            {
                Email = info.Principal.FindFirstValue(ClaimTypes.Email);
            }
            var user = await Database.UserManager.FindByEmailAsync(Email);

            if (user == null)
            {
                User checkUser;
                int  i = 1;
                do
                {
                    checkUser = Database.Users.Find(x => x.UserName == Name).FirstOrDefault();
                    if (checkUser != null)
                    {
                        Name += i.ToString();
                    }
                }while (checkUser != null);
                if (provider == "Facebook")
                {
                    picture = $"https://graph.facebook.com/{identifier}/picture";
                }
                else
                {
                    picture = "https://i03.fotocdn.net/s118/60ff0fe19bf91339/user_l/2688937826.jpg";
                }
                var registerUser = new User
                {
                    UserName        = Name,
                    Email           = Email,
                    EmailConfirmed  = true,
                    ProfileImageUrl = picture
                };
                var registerResult = await Database.UserManager.CreateAsync(registerUser);

                var roleResult = await Database.UserManager.AddToRoleAsync(registerUser, "customer");

                if (!registerResult.Succeeded || !roleResult.Succeeded)
                {
                    throw new ValidationException(registerResult.Errors.ToList()[0].Description + " " + roleResult.Errors.ToList()[0].Description);
                }
            }
            user = await Database.UserManager.FindByEmailAsync(Email);

            var role = await Database.UserManager.GetRolesAsync(user);

            IdentityOptions _options        = new IdentityOptions();
            var             tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim("UserID", user.Id.ToString()),
                    new Claim(_options.ClaimsIdentity.RoleClaimType, role.FirstOrDefault())
                }),
                Expires            = DateTime.UtcNow.AddHours(1),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey
                                                                (Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)),
                                                            SecurityAlgorithms.HmacSha256Signature)
            };
            var tokenHandler  = new JwtSecurityTokenHandler();
            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token         = tokenHandler.WriteToken(securityToken);

            return(token);
        }
예제 #22
0
        public async Task PasswordSignInFailsWithWrongPasswordCanAccessFailedAndLockout()
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            var lockedout = false;
            manager.Setup(m => m.AccessFailedAsync(user)).Returns(() =>
            {
                lockedout = true;
                return Task.FromResult(IdentityResult.Success);
            }).Verifiable();
            manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
            manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
            manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
            var context = new Mock<HttpContext>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);

            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);

            // Assert
            Assert.False(result.Succeeded);
            Assert.True(result.IsLockedOut);
            manager.Verify();
        }
예제 #23
0
        /// <summary>
        /// 用户 配置
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        private static IdentityOptions ConfigurationUser(this IdentityOptions options)
        {
            options.User.RequireUniqueEmail = true; // 用户邮箱必须唯一

            return(options);
        }
예제 #24
0
        public async Task CanRequireConfirmedPhoneNumberForPasswordSignIn(bool confirmed)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.IsPhoneNumberConfirmedAsync(user)).ReturnsAsync(confirmed).Verifiable();
            var context = new Mock<HttpContext>();
            var auth = new Mock<AuthenticationManager>();
            if (confirmed)
            {
                manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
                context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
                SetupSignIn(auth);
            }

            var identityOptions = new IdentityOptions();
            identityOptions.SignIn.RequireConfirmedPhoneNumber = true;
            var logStore = new StringBuilder();
            var helper = SetupSignInManager(manager.Object, context.Object, logStore, identityOptions);

            // Act
            var result = await helper.PasswordSignInAsync(user, "password", false, false);

            // Assert
            Assert.Equal(confirmed, result.Succeeded);
            Assert.NotEqual(confirmed, result.IsNotAllowed);
            Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
            manager.Verify();
            context.Verify();
            auth.Verify();
        }
예제 #25
0
        /// <summary>
        /// Token 配置
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        private static IdentityOptions ConfigurationToken(this IdentityOptions options)
        {
            //options.Tokens

            return(options);
        }
예제 #26
0
 public WeatherForecastController(ILogger <WeatherForecastController> logger, IdentityOptions identityOptions)
 {
     _logger          = logger;
     _identityOptions = identityOptions;
 }
예제 #27
0
 /// <summary>
 /// ClaimsIdentity 配置
 /// </summary>
 /// <param name="options"></param>
 /// <returns></returns>
 private static IdentityOptions ConfigurationClaimsIdentity(this IdentityOptions options)
 {
     options.ClaimsIdentity.UserIdClaimType = JwtRegisteredClaimNames.Sub;
     return(options);
 }
 public ExternalApplicationStorage(IdentityOptions identityOptions)
 {
     _identityOptions = identityOptions;
 }
예제 #29
0
        private static SignInManager <TUser> SetupSignInManager <TUser>(UserManager <TUser> manager,
                                                                        HttpContext context, ILogger logger          = null, IdentityOptions identityOptions = null,
                                                                        IAuthenticationSchemeProvider schemeProvider = null) where TUser : class
        {
            var contextAccessor = new Mock <IHttpContextAccessor>();

            contextAccessor.Setup(a => a.HttpContext).Returns(context);
            identityOptions = identityOptions ?? new IdentityOptions();
            var options = new Mock <IOptions <IdentityOptions> >();

            options.Setup(a => a.Value).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory <TUser>(manager, options.Object);

            schemeProvider = schemeProvider ?? new Mock <IAuthenticationSchemeProvider>().Object;
            var sm = new SignInManager <TUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null, schemeProvider, new DefaultUserConfirmation <TUser>());

            sm.Logger = logger ?? (new Mock <ILogger <SignInManager <TUser> > >()).Object;
            return(sm);
        }
예제 #30
0
        public (string name, string surname) GetNameAndSurnameFromClaims(List <Claim> claims, IdentityOptions identityOptions)
        {
            string name    = null;
            string surname = null;

            var givenNameClaim = claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName);

            if (givenNameClaim != null && !givenNameClaim.Value.IsNullOrEmpty())
            {
                name = givenNameClaim.Value;
            }

            var surnameClaim = claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname);

            if (surnameClaim != null && !surnameClaim.Value.IsNullOrEmpty())
            {
                surname = surnameClaim.Value;
            }

            if (name == null || surname == null)
            {
                var nameClaim = claims.FirstOrDefault(c => c.Type == identityOptions.ClaimsIdentity.UserNameClaimType);
                if (nameClaim != null)
                {
                    var nameSurName = nameClaim.Value;
                    if (!nameSurName.IsNullOrEmpty())
                    {
                        var lastSpaceIndex = nameSurName.LastIndexOf(' ');
                        if (lastSpaceIndex < 1 || lastSpaceIndex > (nameSurName.Length - 2))
                        {
                            name = surname = nameSurName;
                        }
                        else
                        {
                            name    = nameSurName.Substring(0, lastSpaceIndex);
                            surname = nameSurName.Substring(lastSpaceIndex);
                        }
                    }
                }
            }

            return(name, surname);
        }
예제 #31
0
 public CommentsService(IUnitOfWork unitOfWork,
                        IdentityOptions identity)
 {
     _unitOfWork = unitOfWork;
     _identity   = identity;
 }
        public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims, bool supportRoleClaims)
        {
            // Setup
            var userManager = MockHelpers.MockUserManager<TestUser>();
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var user = new TestUser { UserName = "******" };
            userManager.Setup(m => m.SupportsUserClaim).Returns(supportClaims);
            userManager.Setup(m => m.SupportsUserRole).Returns(supportRoles);
            userManager.Setup(m => m.GetUserIdAsync(user)).ReturnsAsync(user.Id);
            userManager.Setup(m => m.GetUserNameAsync(user)).ReturnsAsync(user.UserName);
            var roleClaims = new[] { "Admin", "Local" };
            if (supportRoles)
            {
                userManager.Setup(m => m.GetRolesAsync(user)).ReturnsAsync(roleClaims);
                roleManager.Setup(m => m.SupportsRoleClaims).Returns(supportRoleClaims);
            }
            var userClaims = new[] { new Claim("Whatever", "Value"), new Claim("Whatever2", "Value2") };
            if (supportClaims)
            {
                userManager.Setup(m => m.GetClaimsAsync(user)).ReturnsAsync(userClaims);
            }
            userManager.Object.Options = new IdentityOptions();

            var admin = new TestRole() { Name = "Admin" };
            var local = new TestRole() { Name = "Local" };
            var adminClaims = new[] { new Claim("AdminClaim1", "Value1"), new Claim("AdminClaim2", "Value2") };
            var localClaims = new[] { new Claim("LocalClaim1", "Value1"), new Claim("LocalClaim2", "Value2") };
            if (supportRoleClaims)
            {
                roleManager.Setup(m => m.FindByNameAsync("Admin")).ReturnsAsync(admin);
                roleManager.Setup(m => m.FindByNameAsync("Local")).ReturnsAsync(local);
                roleManager.Setup(m => m.GetClaimsAsync(admin)).ReturnsAsync(adminClaims);
                roleManager.Setup(m => m.GetClaimsAsync(local)).ReturnsAsync(localClaims);
            }

            var options = new Mock<IOptions<IdentityOptions>>();
            var identityOptions = new IdentityOptions();
            options.Setup(a => a.Options).Returns(identityOptions);
            var factory = new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager.Object, roleManager.Object, options.Object);

            // Act
            var principal = await factory.CreateAsync(user);
            var identity = principal.Identities.First();

            // Assert
            var manager = userManager.Object;
            Assert.NotNull(identity);
            Assert.Equal(1, principal.Identities.Count());
            Assert.Equal(IdentityOptions.ApplicationCookieAuthenticationType, identity.AuthenticationType);
            var claims = identity.Claims.ToList();
            Assert.NotNull(claims);
            Assert.True(
                claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName));
            Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id));
            Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin"));
            Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local"));
            foreach (var cl in userClaims)
            {
                Assert.Equal(supportClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            foreach (var cl in adminClaims)
            {
                Assert.Equal(supportRoleClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            foreach (var cl in localClaims)
            {
                Assert.Equal(supportRoleClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            userManager.VerifyAll();
            roleManager.VerifyAll();
        }
예제 #33
0
    private static SignInManager <PocoUser> SetupSignInManager(UserManager <PocoUser> manager, HttpContext context, ILogger logger = null, IdentityOptions identityOptions = null, IAuthenticationSchemeProvider schemeProvider = null)
    {
        var contextAccessor = new Mock <IHttpContextAccessor>();

        contextAccessor.Setup(a => a.HttpContext).Returns(context);
        var roleManager = MockHelpers.MockRoleManager <PocoRole>();

        identityOptions = identityOptions ?? new IdentityOptions();
        var options = new Mock <IOptions <IdentityOptions> >();

        options.Setup(a => a.Value).Returns(identityOptions);
        var claimsFactory = new UserClaimsPrincipalFactory <PocoUser, PocoRole>(manager, roleManager.Object, options.Object);

        schemeProvider = schemeProvider ?? new Mock <IAuthenticationSchemeProvider>().Object;
        var sm = new SignInManager <PocoUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null, schemeProvider, new DefaultUserConfirmation <PocoUser>());

        sm.Logger = logger ?? NullLogger <SignInManager <PocoUser> > .Instance;
        return(sm);
    }
 public override void ExplicitVisit(IdentityOptions fragment)
 {
     _fragments.Add(fragment);
 }
예제 #35
0
 public IdentityContext(DbContextOptions <IdentityContext> options, IOptions <IdentityOptions> identityOptions) : base(options)
 {
     _identityOptions = identityOptions.Value;
 }
예제 #36
0
        public async Task PasswordSignInWorksWithNonTwoFactorStore()
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
            manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
            manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
            manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();

            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            SetupSignIn(response);
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object);

            // Act
            var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);

            // Assert
            Assert.True(result.Succeeded);
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
        }
        // to use with DI see:
        // https://levelup.gitconnected.com/add-extra-user-claims-in-asp-net-core-web-applications-1f28c98c9ec6

        // https://stackoverflow.com/questions/42036810/asp-net-core-jwt-mapping-role-claims-to-claimsidentity
        private async Task <IList <Claim> > GetUserClaims(ApplicationUser user)
        {
            // https://tools.ietf.org/html/rfc7519#section-4
            DateTimeOffset  now     = new DateTimeOffset(DateTime.UtcNow);
            IdentityOptions options = new IdentityOptions();
            List <Claim>    claims  = new List <Claim>
            {
                // (SUB) the principal that is the subject of the JWT
                new Claim(RegisteredClaims.Sub, user.UserName),

                // (JWT ID) provides a unique identifier for the JWT
                new Claim(RegisteredClaims.Jti, Guid.NewGuid().ToString()),

                // (NBF)
                new Claim(RegisteredClaims.Nbf,
                          (now - new TimeSpan(0, 0, 10)).ToUnixTimeSeconds().ToString()),

                new Claim(options.ClaimsIdentity.UserIdClaimType, user.Id.ToString()),
                new Claim(options.ClaimsIdentity.UserNameClaimType, user.UserName),

                // (IAT) issued at
                new Claim(RegisteredClaims.Iat, now.ToUnixTimeSeconds().ToString()),

                // email and its confirmation
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
                          user.Email),
                // this claim name is arbitrary
                new Claim("vfd", user.EmailConfirmed? "true" : "false")
            };

            // claims from user claims
            IList <Claim> userClaims = await _userManager.GetClaimsAsync(user);

            claims.AddRange(userClaims);

            // claims from user roles
            IList <string> userRoles = await _userManager.GetRolesAsync(user);

            foreach (string userRole in userRoles)
            {
                claims.Add(new Claim(ClaimTypes.Role, userRole));
                ApplicationRole role = await _roleManager.FindByNameAsync(userRole);

                if (role != null && _roleManager.SupportsRoleClaims)
                {
                    IList <Claim> roleClaims = await _roleManager.GetClaimsAsync(role);

                    foreach (Claim roleClaim in roleClaims)
                    {
                        claims.Add(roleClaim);
                    }
                }
            }

            // claims from additional user properties
            // http://docs.oasis-open.org/imi/identity/v1.0/os/identity-1.0-spec-os.html#_Toc229451870

            claims.Add(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
                                 user.FirstName));
            claims.Add(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
                                 user.LastName));

            return(claims);
        }
예제 #38
0
        public async Task CanExternalSignIn(bool isPersistent, bool supportsLockout)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            const string loginProvider = "login";
            const string providerKey = "fookey";
            var manager = SetupUserManager(user);
            manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable();
            if (supportsLockout)
            {
                manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
            }
            manager.Setup(m => m.FindByLoginAsync(loginProvider, providerKey)).ReturnsAsync(user).Verifiable();

            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            SetupSignIn(response, user.Id, isPersistent, loginProvider);
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            response.Setup(r => r.SignOut(IdentityOptions.ExternalCookieAuthenticationScheme)).Verifiable();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, null);
            helper.Logger = logger.Object;
            string expectedScope = string.Format("{0} for {1}: {2}", "ExternalLoginSignInAsync", "user", user.Id);
            string expectedLog = string.Format("{0} : {1}", "ExternalLoginSignInAsync", "Succeeded");

            // Act
            var result = await helper.ExternalLoginSignInAsync(loginProvider, providerKey, isPersistent);

            // Assert
            Assert.True(result.Succeeded);
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedLog));
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedScope));
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
        }
예제 #39
0
        public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims, bool supportRoleClaims)
        {
            // Setup
            var userManager = MockHelpers.MockUserManager <TestUser>();
            var roleManager = MockHelpers.MockRoleManager <TestRole>();
            var user        = new TestUser {
                UserName = "******"
            };

            userManager.Setup(m => m.SupportsUserClaim).Returns(supportClaims);
            userManager.Setup(m => m.SupportsUserRole).Returns(supportRoles);
            userManager.Setup(m => m.GetUserIdAsync(user, CancellationToken.None)).ReturnsAsync(user.Id);
            userManager.Setup(m => m.GetUserNameAsync(user, CancellationToken.None)).ReturnsAsync(user.UserName);
            var roleClaims = new[] { "Admin", "Local" };

            if (supportRoles)
            {
                userManager.Setup(m => m.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(roleClaims);
                roleManager.Setup(m => m.SupportsRoleClaims).Returns(supportRoleClaims);
            }
            var userClaims = new[] { new Claim("Whatever", "Value"), new Claim("Whatever2", "Value2") };

            if (supportClaims)
            {
                userManager.Setup(m => m.GetClaimsAsync(user, CancellationToken.None)).ReturnsAsync(userClaims);
            }
            userManager.Object.Options = new IdentityOptions();

            var admin = new TestRole()
            {
                Name = "Admin"
            };
            var local = new TestRole()
            {
                Name = "Local"
            };
            var adminClaims = new[] { new Claim("AdminClaim1", "Value1"), new Claim("AdminClaim2", "Value2") };
            var localClaims = new[] { new Claim("LocalClaim1", "Value1"), new Claim("LocalClaim2", "Value2") };

            if (supportRoleClaims)
            {
                roleManager.Setup(m => m.FindByNameAsync("Admin", CancellationToken.None)).ReturnsAsync(admin);
                roleManager.Setup(m => m.FindByNameAsync("Local", CancellationToken.None)).ReturnsAsync(local);
                roleManager.Setup(m => m.GetClaimsAsync(admin, CancellationToken.None)).ReturnsAsync(adminClaims);
                roleManager.Setup(m => m.GetClaimsAsync(local, CancellationToken.None)).ReturnsAsync(localClaims);
            }

            var options         = new Mock <IOptions <IdentityOptions> >();
            var identityOptions = new IdentityOptions();

            options.Setup(a => a.Options).Returns(identityOptions);
            var factory = new ClaimsIdentityFactory <TestUser, TestRole>(userManager.Object, roleManager.Object, options.Object);

            // Act
            var identity = await factory.CreateAsync(user);

            // Assert
            var manager = userManager.Object;

            Assert.NotNull(identity);
            Assert.Equal(IdentityOptions.ApplicationCookieAuthenticationType, identity.AuthenticationType);
            var claims = identity.Claims.ToList();

            Assert.NotNull(claims);
            Assert.True(
                claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName));
            Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id));
            Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin"));
            Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local"));
            foreach (var cl in userClaims)
            {
                Assert.Equal(supportClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            foreach (var cl in adminClaims)
            {
                Assert.Equal(supportRoleClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            foreach (var cl in localClaims)
            {
                Assert.Equal(supportRoleClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
            }
            userManager.VerifyAll();
            roleManager.VerifyAll();
        }
예제 #40
0
        public async Task RememberClientStoresUserId()
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);

            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            response.Setup(r => r.SignIn(
                IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme,
                It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
                    && i.Identities.First().AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType),
                It.Is<AuthenticationProperties>(v => v.IsPersistent == true))).Verifiable();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object).Verifiable();
            options.Setup(a => a.Options).Returns(identityOptions).Verifiable();

            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object);

            // Act
            await helper.RememberTwoFactorClientAsync(user);

            // Assert
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
            options.Verify();
        }
예제 #41
0
        private void ConfigureAuthServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole <int> >(
                options => { options.Lockout.AllowedForNewUsers = false; })
            .AddEntityFrameworkStores <BuildAssetRegistryContext>();

            services.AddSingleton <IAuthenticationSchemeProvider, ContextAwareAuthenticationSchemeProvider>();
            services.AddAuthentication()
            .AddOAuth <GitHubAuthenticationOptions, GitHubAuthenticationHandler>(
                GitHubScheme,
                options =>
            {
                IConfigurationSection ghAuthConfig = Configuration.GetSection("GitHubAuthentication");
                ghAuthConfig.Bind(options);
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        var logger = context.HttpContext.RequestServices.GetRequiredService <ILogger <Startup> >();
                        logger.LogInformation("Reading user roles from GitHub.");
                        foreach (string role in await GetGithubRolesAsync(context.AccessToken))
                        {
                            context.Identity.AddClaim(
                                new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, GitHubScheme));
                        }
                    },
                    OnRemoteFailure = context =>
                    {
                        var logger = context.HttpContext.RequestServices.GetRequiredService <ILogger <GitHubAuthenticationHandler> >();
                        logger.LogError(context.Failure, "Github authentication failed.");
                        var res        = context.HttpContext.Response;
                        res.StatusCode = (int)HttpStatusCode.Forbidden;
                        context.HandleResponse();
                        context.HttpContext.Items["ErrorMessage"] = "Authentication failed.";
                        return(Task.CompletedTask);
                    },
                };
            })
            .AddPersonalAccessToken <ApplicationUser>(
                options =>
            {
                options.Events = new PersonalAccessTokenEvents <ApplicationUser>
                {
                    OnSetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        int userId = context.User.Id;
                        var token  = new ApplicationUserPersonalAccessToken
                        {
                            ApplicationUserId = userId,
                            Name    = context.Name,
                            Hash    = context.Hash,
                            Created = DateTimeOffset.UtcNow
                        };
                        await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token);
                        await dbContext.SaveChangesAsync();

                        return(token.Id);
                    },
                    OnGetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        ApplicationUserPersonalAccessToken token = await dbContext
                                                                   .Set <ApplicationUserPersonalAccessToken>()
                                                                   .Where(t => t.Id == context.TokenId)
                                                                   .Include(t => t.ApplicationUser)
                                                                   .FirstOrDefaultAsync();
                        if (token != null)
                        {
                            context.Success(token.Hash, token.ApplicationUser);
                        }
                    },
                    OnValidatePrincipal = async context =>
                    {
                        ApplicationUser user = context.User;
                        var dbContext        = context.HttpContext.RequestServices
                                               .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = context.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = context.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();

                        await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager);

                        ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                        context.ReplacePrincipal(principal);
                    }
                };
            });
            services.ConfigureExternalCookie(
                options =>
            {
                options.ExpireTimeSpan     = TimeSpan.FromMinutes(30);
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = 401;
                            return(Task.CompletedTask);
                        }

                        ctx.Response.Redirect(ctx.RedirectUri);
                        return(Task.CompletedTask);
                    },
                    OnRedirectToAccessDenied = ctx =>
                    {
                        ctx.Response.StatusCode = 403;
                        return(Task.CompletedTask);
                    },
                };
            });
            services.ConfigureApplicationCookie(
                options =>
            {
                options.ExpireTimeSpan    = LoginCookieLifetime;
                options.SlidingExpiration = true;
                options.Events            = new CookieAuthenticationEvents
                {
                    OnSigningIn = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();

                        var user = await userManager.GetUserAsync(ctx.Principal);
                        await UpdateUserTokenAsync(dbContext, userManager, user, info);

                        IdentityOptions identityOptions = ctx.HttpContext.RequestServices
                                                          .GetRequiredService <IOptions <IdentityOptions> >()
                                                          .Value;

                        // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference
                        Claim claim = ctx.Principal.Claims.Single(
                            c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType);
                        Claim[] claims = { claim };
                        var identity   = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
                        ctx.Principal  = new ClaimsPrincipal(identity);
                    },
                    OnValidatePrincipal = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();


                        // extract the userId from the ClaimsPrincipal and read the user from the Db
                        ApplicationUser user = await userManager.GetUserAsync(ctx.Principal);
                        if (user == null)
                        {
                            ctx.RejectPrincipal();
                        }
                        else
                        {
                            await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager);

                            ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                            ctx.ReplacePrincipal(principal);
                        }
                    }
                };
            });

            services.AddAuthorization(
                options =>
            {
                options.AddPolicy(
                    MsftAuthorizationPolicyName,
                    policy =>
                {
                    policy.RequireAuthenticatedUser();
                    if (!HostingEnvironment.IsDevelopment())
                    {
                        policy.RequireRole("github:team:dotnet:dnceng", "github:team:dotnet:arcade-contrib");
                    }
                });
            });

            services.Configure <MvcOptions>(
                options =>
            {
                options.Conventions.Add(new DefaultAuthorizeActionModelConvention(MsftAuthorizationPolicyName));
            });
        }
예제 #42
0
        public void SignOutCallsContextResponseSignOut(string authenticationScheme)
        {
            // Setup
            var manager = MockHelpers.MockUserManager<TestUser>();
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            context.Setup(c => c.Response).Returns(response.Object).Verifiable();
            response.Setup(r => r.SignOut(authenticationScheme)).Verifiable();
            response.Setup(r => r.SignOut(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme)).Verifiable();
            response.Setup(r => r.SignOut(IdentityOptions.ExternalCookieAuthenticationScheme)).Verifiable();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            IdentityOptions.ApplicationCookieAuthenticationScheme = authenticationScheme;
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object, null);
            helper.Logger = logger.Object;

            // Act
            helper.SignOut();

            // Assert
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
            claimsFactory.Verify();
        }
예제 #43
0
        private void ConfigureAuthServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole <int> >(
                options => { options.Lockout.AllowedForNewUsers = false; })
            .AddEntityFrameworkStores <BuildAssetRegistryContext>();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = options.DefaultChallengeScheme = options.DefaultScheme = "Contextual";
                options.DefaultSignInScheme       = IdentityConstants.ExternalScheme;
            })
            .AddPolicyScheme("Contextual", "Contextual",
                             policyOptions => { policyOptions.ForwardDefaultSelector = ctx => ctx.Request.Path.StartsWithSegments("/api") ? PersonalAccessTokenDefaults.AuthenticationScheme : IdentityConstants.ApplicationScheme; })
            .AddGitHubOAuth(Configuration.GetSection("GitHubAuthentication"), GitHubScheme)
            .AddPersonalAccessToken <ApplicationUser>(
                options =>
            {
                options.Events = new PersonalAccessTokenEvents <ApplicationUser>
                {
                    OnSetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        int userId = context.User.Id;
                        var token  = new ApplicationUserPersonalAccessToken
                        {
                            ApplicationUserId = userId,
                            Name    = context.Name,
                            Hash    = context.Hash,
                            Created = DateTimeOffset.UtcNow
                        };
                        await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token);
                        await dbContext.SaveChangesAsync();

                        return(token.Id);
                    },
                    OnGetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        ApplicationUserPersonalAccessToken token = await dbContext
                                                                   .Set <ApplicationUserPersonalAccessToken>()
                                                                   .Where(t => t.Id == context.TokenId)
                                                                   .Include(t => t.ApplicationUser)
                                                                   .FirstOrDefaultAsync();
                        if (token != null)
                        {
                            context.Success(token.Hash, token.ApplicationUser);
                        }
                    },
                    OnValidatePrincipal = async context =>
                    {
                        ApplicationUser user = context.User;
                        var dbContext        = context.HttpContext.RequestServices
                                               .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = context.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = context.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var gitHubClaimResolver = context.HttpContext.RequestServices
                                                  .GetRequiredService <GitHubClaimResolver>();

                        await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver);

                        ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                        context.ReplacePrincipal(principal);
                    }
                };
            });
            services.ConfigureExternalCookie(
                options =>
            {
                options.ExpireTimeSpan     = TimeSpan.FromMinutes(30);
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = 401;
                            return(Task.CompletedTask);
                        }

                        ctx.Response.Redirect(ctx.RedirectUri);
                        return(Task.CompletedTask);
                    },
                    OnRedirectToAccessDenied = ctx =>
                    {
                        ctx.Response.StatusCode = 403;
                        return(Task.CompletedTask);
                    },
                };
            });
            services.ConfigureApplicationCookie(
                options =>
            {
                options.ExpireTimeSpan     = LoginCookieLifetime;
                options.SlidingExpiration  = true;
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnSigningIn = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();

                        var user = await userManager.GetUserAsync(ctx.Principal);
                        await UpdateUserTokenAsync(dbContext, userManager, user, info);

                        IdentityOptions identityOptions = ctx.HttpContext.RequestServices
                                                          .GetRequiredService <IOptions <IdentityOptions> >()
                                                          .Value;

                        // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference
                        Claim claim = ctx.Principal.Claims.First(
                            c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType);
                        Claim[] claims = { claim };
                        var identity   = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
                        ctx.Principal  = new ClaimsPrincipal(identity);
                    },
                    OnValidatePrincipal = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var gitHubClaimResolver = ctx.HttpContext.RequestServices
                                                  .GetRequiredService <GitHubClaimResolver>();

                        // extract the userId from the ClaimsPrincipal and read the user from the Db
                        ApplicationUser user = await userManager.GetUserAsync(ctx.Principal);
                        if (user == null)
                        {
                            ctx.RejectPrincipal();
                        }
                        else
                        {
                            await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver);

                            ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                            ctx.ReplacePrincipal(principal);
                        }
                    }
                };
            });

            services.AddAuthorization(
                options =>
            {
                options.AddPolicy(
                    MsftAuthorizationPolicyName,
                    policy =>
                {
                    policy.RequireAuthenticatedUser();
                    if (!HostingEnvironment.IsDevelopment())
                    {
                        policy.RequireRole(GitHubClaimResolver.GetTeamRole("dotnet", "dnceng"), GitHubClaimResolver.GetTeamRole("dotnet", "arcade-contrib"));
                    }
                });
            });

            services.Configure <MvcOptions>(
                options =>
            {
                options.Conventions.Add(new DefaultAuthorizeActionModelConvention(MsftAuthorizationPolicyName));
            });
        }
예제 #44
0
        public async Task PasswordSignInFailsWithUnknownUser()
        {
            // Setup
            var manager = MockHelpers.MockUserManager<TestUser>();
            manager.Setup(m => m.FindByNameAsync("bogus")).ReturnsAsync(null).Verifiable();
            var context = new Mock<HttpContext>();
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);

            // Act
            var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);

            // Assert
            Assert.False(result.Succeeded);
            manager.Verify();
            context.Verify();
            contextAccessor.Verify();
        }
예제 #45
0
 /// <summary>
 /// Creates new instance of password check service.
 /// </summary>
 /// <param name="options"></param>
 public PasswordCheckService(UserManager <ApplicationUser> userManager)
 {
     Options = userManager.Options;
 }
예제 #46
0
        public async Task CanRequireConfirmedPhoneNumberForPasswordSignIn(bool confirmed)
        {
            // Setup
            var user = new TestUser { UserName = "******" };
            var manager = SetupUserManager(user);
            manager.Setup(m => m.IsPhoneNumberConfirmedAsync(user)).ReturnsAsync(confirmed).Verifiable();
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            if (confirmed)
            {
                manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
                context.Setup(c => c.Response).Returns(response.Object).Verifiable();
                SetupSignIn(response);
            }

            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
            var roleManager = MockHelpers.MockRoleManager<TestRole>();
            var identityOptions = new IdentityOptions();
            identityOptions.SignIn.RequireConfirmedPhoneNumber = true;
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Options).Returns(identityOptions);
            var claimsFactory = new Mock<UserClaimsPrincipalFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
            var logStore = new StringBuilder();
            var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
            var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object, null);
            helper.Logger = logger.Object;
            string expectedScope = string.Format("{0} for {1}: {2}", "PasswordSignInAsync", "user", user.Id);
            string expectedLog = string.Format("{0} : {1}", "CanSignInAsync", confirmed.ToString());

            // Act
            var result = await helper.PasswordSignInAsync(user, "password", false, false);

            // Assert
            Assert.Equal(confirmed, result.Succeeded);
            Assert.NotEqual(confirmed, result.IsNotAllowed);
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedLog));
            Assert.NotEqual(-1, logStore.ToString().IndexOf(expectedScope));
            manager.Verify();
            context.Verify();
            response.Verify();
            contextAccessor.Verify();
        }
예제 #47
0
        public virtual async Task <IActionResult> OnPostAsync(string action)
        {
            ActionHelper.AddTitle(this, "Login");

            // Clean old noitify data
            ViewData["LoginError"] = null;

            await CheckLocalLoginAsync();

            ValidateModel();

            ExternalProviders = await GetExternalProviders();

            EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);

            await ReplaceEmailToUsernameOfInputIfNeeds();

            await IdentityOptions.SetAsync();

            var result = await SignInManager.PasswordSignInAsync(
                LoginInput.UserNameOrEmailAddress,
                LoginInput.Password,
                LoginInput.RememberMe,
                true
                );

            await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
            {
                Identity = IdentitySecurityLogIdentityConsts.Identity,
                Action   = result.ToIdentitySecurityLogAction(),
                UserName = LoginInput.UserNameOrEmailAddress
            });

            if (result.RequiresTwoFactor)
            {
                return(await TwoFactorLoginResultAsync());
            }

            if (result.IsLockedOut)
            {
                ViewData["LoginError"] = L["Please try again after a few minutes"];
                ToastHelper.ToastError(this, L["Please try again after a few minutes"]);
                return(Page());
            }

            if (result.IsNotAllowed)
            {
                ViewData["LoginError"] = L["You are not permitted login right now"];
                ToastHelper.ToastError(this, L["You are not permitted login right now"]);
                return(Page());
            }

            if (!result.Succeeded)
            {
                ViewData["LoginError"] = L["Invalid Username/Email or Password"];
                ToastHelper.ToastError(this, L["Invalid Username/Email or Password"]);
                return(Page());
            }

            //TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
            var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
                       await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);

            Debug.Assert(user != null, nameof(user) + " != null");

            ToastHelper.ToastSuccess(this, L["Login successful"]);

            return(RedirectSafely(ReturnUrl, ReturnUrlHash));
        }
예제 #48
0
 private static SignInManager<TestUser> SetupSignInManager(UserManager<TestUser> manager, HttpContext context, StringBuilder logStore = null, IdentityOptions identityOptions = null)
 {
     var contextAccessor = new Mock<IHttpContextAccessor>();
     contextAccessor.Setup(a => a.HttpContext).Returns(context);
     var roleManager = MockHelpers.MockRoleManager<TestRole>();
     identityOptions = identityOptions ?? new IdentityOptions();
     var options = new Mock<IOptions<IdentityOptions>>();
     options.Setup(a => a.Value).Returns(identityOptions);
     var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
     var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null);
     sm.Logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore ?? new StringBuilder()).Object;
     return sm;
 }
예제 #49
0
        public virtual async Task <IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null)
        {
            //TODO: Did not implemented Identity Server 4 sample for this method (see ExternalLoginCallback in Quickstart of IDS4 sample)

            /* Also did not implement these:
             * - Logout(string logoutId)
             */

            if (remoteError != null)
            {
                Logger.LogWarning($"External login callback error: {remoteError}");
                return(RedirectToPage("./Login"));
            }

            await IdentityOptions.SetAsync();

            var loginInfo = await SignInManager.GetExternalLoginInfoAsync();

            if (loginInfo == null)
            {
                Logger.LogWarning("External login info is not available");
                return(RedirectToPage("./Login"));
            }

            var result = await SignInManager.ExternalLoginSignInAsync(
                loginInfo.LoginProvider,
                loginInfo.ProviderKey,
                isPersistent : false,
                bypassTwoFactor : true
                );

            if (!result.Succeeded)
            {
                await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
                {
                    Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
                    Action   = "Login" + result
                });
            }

            if (result.IsLockedOut)
            {
                throw new UserFriendlyException("Cannot proceed because user is locked out!");
            }

            if (result.Succeeded)
            {
                return(RedirectSafely(returnUrl, returnUrlHash));
            }

            //TODO: Handle other cases for result!

            // Get the information about the user from the external login provider
            var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();

            if (externalLoginInfo == null)
            {
                throw new ApplicationException("Error loading external login information during confirmation.");
            }

            if (!IsEmailRetrievedFromExternalLogin(externalLoginInfo))
            {
                return(RedirectToPage("./Register", new
                {
                    IsExternalLogin = true,
                    ExternalLoginAuthSchema = externalLoginInfo.LoginProvider,
                    ReturnUrl = returnUrl
                }));
            }

            var user = await CreateExternalUserAsync(externalLoginInfo);

            await SignInManager.SignInAsync(user, false);

            await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
            {
                Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
                Action   = result.ToIdentitySecurityLogAction(),
                UserName = user.Name
            });

            return(RedirectSafely(returnUrl, returnUrlHash));
        }
예제 #50
0
 /// <summary>	Constructor. </summary>
 /// <param name="options">	Options for controlling the operation. </param>
 public IdentityDataProvider(IdentityOptions options)
 {
     _options = options ?? throw new ArgumentNullException(nameof(options));
 }
        public async Task OnValidateIdentityDoesNotRejectsWhenNotExpired()
        {
            var user = new TestUser("test");
            var httpContext = new Mock<HttpContext>();
            var userManager = MockHelpers.MockUserManager<TestUser>();
            var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
            var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.FromDays(1) };
            var options = new Mock<IOptions<IdentityOptions>>();
            options.Setup(a => a.Value).Returns(identityOptions);
            var contextAccessor = new Mock<IHttpContextAccessor>();
            contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
            var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
                contextAccessor.Object, claimsManager.Object, options.Object, null);
            signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>(), user.Id)).Throws(new Exception("Shouldn't be called"));
            signInManager.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called"));
            var services = new ServiceCollection();
            services.AddSingleton(options.Object);
            services.AddSingleton(signInManager.Object);
            services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>());
            httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
            var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
            id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));

            var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
                new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
                identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
            var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
            Assert.NotNull(context.Properties);
            Assert.NotNull(context.Options);
            Assert.NotNull(context.Principal);
            await SecurityStampValidator.ValidatePrincipalAsync(context);
            Assert.NotNull(context.Principal);
        }