/// <summary>
        /// Generate the new session for the logged in user. Also, set the appropriate claims for the user in this session.
        /// The multi-factor authentication setting value can be obtained from external logins(in case of AADv2).
        /// </summary>
        /// <returns>Awaitable task</returns>
        public virtual async Task CreateSessionAsync(IOwinContext owinContext, AuthenticatedUser authenticatedUser, bool wasMultiFactorAuthenticated = false)
        {
            // Create a claims identity for the session
            ClaimsIdentity identity = CreateIdentity(authenticatedUser.User, AuthenticationTypes.LocalUser, await GetUserLoginClaims(authenticatedUser, wasMultiFactorAuthenticated));

            // Issue the session token and clean up the external token if present
            owinContext.Authentication.SignIn(new AuthenticationProperties()
            {
                IsPersistent = true
            }, identity);
            owinContext.Authentication.SignOut(AuthenticationTypes.External);

            _telemetryService.TrackUserLogin(authenticatedUser.User, authenticatedUser.CredentialUsed, wasMultiFactorAuthenticated);

            // Write an audit record
            await Auditing.SaveAuditRecordAsync(
                new UserAuditRecord(authenticatedUser.User, AuditedUserAction.Login, authenticatedUser.CredentialUsed));
        }
Example #2
0
        private async Task <Claim[]> GetUserLoginClaims(AuthenticatedUser user, bool wasMultiFactorAuthenticated)
        {
            await _contentObjectService.Refresh();

            var claims = new List <Claim>();

            if (_contentObjectService.LoginDiscontinuationConfiguration.IsLoginDiscontinued(user))
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.DiscontinuedLogin);
            }

            if (user.User.HasPasswordCredential())
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.PasswordLogin);
            }

            if (user.User.HasExternalCredential())
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.ExternalLogin);

                var externalIdentities = user.User
                                         .Credentials
                                         .Where(cred => cred.IsExternal())
                                         .Select(cred => cred.Identity)
                                         .ToArray();

                var identityList = string.Join(" or ", externalIdentities);
                ClaimsExtensions.AddExternalCredentialIdentityClaim(claims, identityList);
            }

            if (user.User.EnableMultiFactorAuthentication)
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.EnabledMultiFactorAuthentication);
            }

            if (wasMultiFactorAuthenticated)
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.WasMultiFactorAuthenticated);
            }

            ClaimsExtensions.AddExternalLoginCredentialTypeClaim(claims, user.CredentialUsed.Type);

            return(claims.ToArray());
        }
Example #3
0
        private async Task <Claim[]> GetDiscontinuedLoginClaims(AuthenticatedUser user)
        {
            await _contentObjectService.Refresh();

            var claims = new List <Claim>();

            if (_contentObjectService.LoginDiscontinuationConfiguration.IsLoginDiscontinued(user))
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.DiscontinuedLogin);
            }

            if (user.User.HasPasswordCredential())
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.PasswordLogin);
            }

            if (user.User.HasExternalCredential())
            {
                ClaimsExtensions.AddBooleanClaim(claims, NuGetClaims.ExternalLogin);
            }

            return(claims.ToArray());
        }
            public async Task GivenNoLinkButEmailMatchingLocalUser_ItDisplaysLogOnViewPresetForSignIn()
            {
                // Arrange
                var existingUser = new User("existingUser") { EmailAddress = "*****@*****.**" };
                var cred = CredentialBuilder.CreateExternalCredential("MicrosoftAccount", "blorg", "Bloog");
                var msAuther = new MicrosoftAccountAuthenticator();
                var msaUI = msAuther.GetUI();
                var authUser = new AuthenticatedUser(
                    Fakes.CreateUser("test", cred),
                    cred);

                GetMock<AuthenticationService>(); // Force a mock to be created
                GetMock<IUserService>()
                    .Setup(u => u.FindByEmailAddress(existingUser.EmailAddress))
                    .Returns(existingUser);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.AuthenticateExternalLogin(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(new [] {
                            new Claim(ClaimTypes.Email, existingUser.EmailAddress)
                        }),
                        Authenticator = msAuther
                    });

                // Act
                var result = await controller.LinkExternalAccount("theReturnUrl");

                // Assert
                var model = ResultAssert.IsView<LogOnViewModel>(result, viewName: "LogOn");
                Assert.Equal(msaUI.AccountNoun, model.External.ProviderAccountNoun);
                Assert.Null(model.External.AccountName);
                Assert.True(model.External.FoundExistingUser);
                Assert.Equal(existingUser.EmailAddress, model.SignIn.UserNameOrEmail);
                Assert.Equal(existingUser.EmailAddress, model.Register.EmailAddress);
            }
            public async Task GivenAssociatedLocalAdminUser_ItChallengesWhenNotUsingRequiredExternalProvider(string providerUsedForLogin, bool shouldChallenge)
            {
                // Arrange
                var enforcedProvider = "AzureActiveDirectory";

                var config = Get<ConfigurationService>();
                config.Current = new AppConfiguration()
                {
                    ConfirmEmailAddresses = false,
                    EnforcedAuthProviderForAdmin = enforcedProvider
                };

                GetMock<AuthenticationService>(); // Force a mock to be created
                var controller = GetController<AuthenticationController>();
                var cred = CredentialBuilder.CreateExternalCredential(providerUsedForLogin, "blorg", "Bloog");
                var authUser = new AuthenticatedUser(
                    Fakes.CreateUser("test", cred),
                    cred);

                authUser.User.Roles.Add(new Role { Name = Constants.AdminRoleName });

                GetMock<AuthenticationService>()
                    .Setup(x => x.AuthenticateExternalLogin(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Authentication = authUser
                    });

                if (shouldChallenge)
                {
                    GetMock<AuthenticationService>()
                        .Setup(x => x.Challenge(enforcedProvider, It.IsAny<string>()))
                        .Returns(new ChallengeResult(enforcedProvider, null))
                        .Verifiable();
                }
                else
                {
                    GetMock<AuthenticationService>()
                       .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                       .Verifiable();
                }

                // Act
                var result = await controller.LinkExternalAccount("theReturnUrl");

                // Assert
                if (shouldChallenge)
                {
                    ResultAssert.IsChallengeResult(result, enforcedProvider);
                }
                else
                {
                    ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                    GetMock<AuthenticationService>().VerifyAll();
                }
            }
            public async Task GivenAssociatedLocalUser_ItCreatesASessionAndSafeRedirectsToReturnUrl()
            {
                // Arrange
                GetMock<AuthenticationService>(); // Force a mock to be created
                var controller = GetController<AuthenticationController>();
                var cred = CredentialBuilder.CreateExternalCredential("MicrosoftAccount", "blorg", "Bloog");
                var authUser = new AuthenticatedUser(
                    Fakes.CreateUser("test", cred),
                    cred);
                GetMock<AuthenticationService>()
                    .Setup(x => x.AuthenticateExternalLogin(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Authentication = authUser
                    });

                // Act
                var result = await controller.LinkExternalAccount("theReturnUrl");

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>()
                    .Verify(x => x.CreateSession(controller.OwinContext, authUser.User));
            }
            public async Task GivenAdminLogsInWithExternalIdentity_ItChallengesWhenNotUsingRequiredExternalProvider(string providerUsedForLogin, bool shouldChallenge)
            {
                // Arrange
                var enforcedProvider = "AzureActiveDirectory";

                var config = Get<ConfigurationService>();
                config.Current = new AppConfiguration()
                {
                    ConfirmEmailAddresses = false,
                    EnforcedAuthProviderForAdmin = enforcedProvider
                };

                var externalCred = CredentialBuilder.CreateExternalCredential(providerUsedForLogin, "blorg", "Bloog");

                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        EmailConfirmationToken = "t0k3n",
                        Roles =
                        {
                            new Role { Name = Constants.AdminRoleName }
                        }
                    },
                    externalCred);

                GetMock<AuthenticationService>()
                    .Setup(x => x.Register("theUsername", "theEmailAddress", externalCred))
                    .CompletesWith(authUser);

                EnableAllAuthenticators(Get<AuthenticationService>());
                var controller = GetController<AuthenticationController>();

                if (shouldChallenge)
                {
                    GetMock<AuthenticationService>()
                        .Setup(x => x.Challenge(enforcedProvider, It.IsAny<string>()))
                        .Returns(new ChallengeResult(enforcedProvider, null))
                        .Verifiable();
                }
                else
                {
                    GetMock<AuthenticationService>()
                       .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                       .Verifiable();
                }

                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Act
                var result = await controller.Register(
                    new LogOnViewModel()
                    {
                        Register = new RegisterViewModel
                        {
                            Username = "******",
                            EmailAddress = "theEmailAddress",
                        }
                    }, "/theReturnUrl", linkingAccount: true);

                // Assert
                if (shouldChallenge)
                {
                    ResultAssert.IsChallengeResult(result, enforcedProvider);
                }
                else
                {
                    ResultAssert.IsSafeRedirectTo(result, "/theReturnUrl");
                }
                GetMock<AuthenticationService>().VerifyAll();
            }
            public async Task WritesAnAuditRecord()
            {
                // Arrange
                var service = Get<AuthenticationService>();
                var context = Fakes.CreateOwinContext();

                var credential = Fakes.Admin.Credentials.SingleOrDefault(
                    c => String.Equals(c.Type, CredentialTypes.Password.Pbkdf2, StringComparison.OrdinalIgnoreCase));

                var authenticatedUser = new AuthenticatedUser(Fakes.Admin, credential);

                // Act
                await service.CreateSessionAsync(context, authenticatedUser);

                // Assert
                var authenticationService = Get<AuthenticationService>();
                Assert.True(authenticationService.Auditing.WroteRecord<UserAuditRecord>(ar =>
                    ar.Action == AuditedUserAction.Login &&
                    ar.Username == Fakes.Admin.Username));
            }
        private async Task<AuthenticatedUser> AssociateCredential(AuthenticatedUser user)
        {
            var result = await _authService.ReadExternalLoginCredential(OwinContext);
            if (result.ExternalIdentity == null)
            {
                // User got here without an external login cookie (or an expired one)
                // Send them to the logon action
                return null;
            }

            await _authService.AddCredential(user.User, result.Credential);

            // Notify the user of the change
            _messageService.SendCredentialAddedNotice(user.User, result.Credential);

            return new AuthenticatedUser(user.User, result.Credential);
        }
            public async Task WillCreateAndLogInTheUserWhenNotLinking()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        EmailConfirmationToken = "t0k3n"
                    },
                    new Credential());
                GetMock<AuthenticationService>()
                    .Setup(x => x.Register("theUsername", "*****@*****.**", It.IsAny<Credential>()))
                    .CompletesWith(authUser);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();

                // Act
                var result = await controller.Register(
                    new LogOnViewModel()
                    {
                        Register = new RegisterViewModel
                        {
                            Username = "******",
                            Password = "******",
                            EmailAddress = "*****@*****.**",
                        }
                    }, "/theReturnUrl", linkingAccount: false);

                // Assert
                GetMock<AuthenticationService>().VerifyAll();

                var expectedAddress = new MailAddress(authUser.User.UnconfirmedEmailAddress, authUser.User.Username);
                GetMock<IMessageService>()
                    .Verify(x => x.SendNewAccountEmail(
                        expectedAddress,
                        "https://nuget.local/account/confirm/theUsername/t0k3n"));
                ResultAssert.IsSafeRedirectTo(result, "/theReturnUrl");
            }
            public async Task GivenValidExternalAuth_ItLinksCredentialSendsEmailAndLogsIn()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { EmailAddress = "*****@*****.**" },
                    new Credential() { Type = "Foo" });
                var externalCred = CredentialBuilder.CreateExternalCredential("MicrosoftAccount", "blorg", "Bloog");

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authUser);
                GetMock<AuthenticationService>()
                    .Setup(x => x.AddCredential(authUser.User, externalCred))
                    .Completes()
                    .Verifiable();
                GetMock<IMessageService>()
                    .Setup(x => x.SendCredentialAddedNotice(authUser.User, externalCred))
                    .Verifiable();

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>().VerifyAll();
                GetMock<IMessageService>().VerifyAll();
            }
            public async Task GivenExpiredExternalAuth_ItRedirectsBackToLogOnWithExternalAuthExpiredMessage()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { EmailAddress = "*****@*****.**" },
                    new Credential() { Type = "Foo" });

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authUser);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult());

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                VerifyExternalLinkExpiredResult(controller, result);
                GetMock<AuthenticationService>()
                    .Verify(x => x.CreateSession(It.IsAny<IOwinContext>(), It.IsAny<User>()), Times.Never());
            }
            public async Task WillLogTheUserOnWithUsernameEvenWithoutConfirmedEmailAddress()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { UnconfirmedEmailAddress = "*****@*****.**" },
                    new Credential() { Type = "Foo" });
                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate("*****@*****.**", "thePassword"))
                    .CompletesWith(authUser);
                var controller = GetController<AuthenticationController>();
                GetMock<AuthenticationService>()
                    .Setup(a => a.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            "*****@*****.**",
                            "thePassword")),
                    "theReturnUrl", linkingAccount: false);

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>().VerifyAll();
            }
            public async Task GivenAdminLogsInWithValidExternalAuth_ItChallengesWhenNotUsingRequiredExternalProvider(string providerUsedForLogin, bool shouldChallenge)
            {
                var enforcedProvider = "AzureActiveDirectory";

                var mockConfig = GetMock<IGalleryConfigurationService>();
                mockConfig.Setup(x => x.Current).Returns(new AppConfiguration
                {
                    ConfirmEmailAddresses = false,
                    EnforcedAuthProviderForAdmin = enforcedProvider
                });

                var externalCred = new CredentialBuilder().CreateExternalCredential(providerUsedForLogin, "blorg", "Bloog");

                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        Roles =
                        {
                            new Role { Name = Constants.AdminRoleName }
                        }
                    },
                    externalCred);
                
                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authUser);

                GetMock<AuthenticationService>()
                    .Setup(x => x.AddCredential(authUser.User, externalCred))
                    .Completes()
                    .Verifiable();

                GetMock<IMessageService>()
                    .Setup(x => x.SendCredentialAddedNotice(authUser.User, externalCred))
                    .Verifiable();

                EnableAllAuthenticators(Get<AuthenticationService>());
                var controller = GetController<AuthenticationController>();

                if (shouldChallenge)
                {
                    GetMock<AuthenticationService>()
                        .Setup(x => x.Challenge(enforcedProvider, It.IsAny<string>()))
                        .Returns(new ChallengeResult(enforcedProvider, null))
                        .Verifiable();
                }
                else
                {
                    GetMock<AuthenticationService>()
                       .Setup(x => x.CreateSessionAsync(controller.OwinContext, It.IsAny<AuthenticatedUser>()))
                       .Returns(Task.FromResult(0))
                       .Verifiable();
                }
                
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                if (shouldChallenge)
                {
                    ResultAssert.IsChallengeResult(result, enforcedProvider);
                }
                else
                {
                    ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                }
                GetMock<AuthenticationService>().VerifyAll();
                GetMock<IMessageService>().VerifyAll();
            }
            public async Task CanLogTheUserOnWithUserName()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { EmailAddress = "*****@*****.**" },
                    new Credential { Type = "Foo" });
                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser);

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authResult);

                var controller = GetController<AuthenticationController>();
                GetMock<AuthenticationService>()
                    .Setup(a => a.CreateSessionAsync(controller.OwinContext, authUser))
                    .Returns(Task.FromResult(0))
                    .Verifiable();

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: false);

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>().VerifyAll();
            }
            public void VerifyShouldChallenge(string providerUsedForLogin, bool shouldChallenge)
            {
                // Arrange
                var enforcedProvider = "AzureActiveDirectory";

                EnableAllAuthenticators(Get<AuthenticationService>());

                var controller = GetController<AuthenticationController>();
                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        EmailAddress = "*****@*****.**",
                        Roles =
                        {
                            new Role { Name = Constants.AdminRoleName }
                        }
                    },
                    new Credential { Type = providerUsedForLogin });

                // Act
                ActionResult challengeResult;
                var result = controller.ShouldChallengeEnforcedProvider(enforcedProvider, authUser, null, out challengeResult);

                // Assert
                Assert.Equal(shouldChallenge, result);
                if (shouldChallenge)
                {
                    ResultAssert.IsChallengeResult(challengeResult, enforcedProvider);
                }
            }
        internal bool ShouldChallengeEnforcedProvider(string enforcedProviders, AuthenticatedUser authenticatedUser, string returnUrl, out ActionResult challenge)
        {
            if (!string.IsNullOrEmpty(enforcedProviders)
                && authenticatedUser.CredentialUsed.Type != null
                && authenticatedUser.User.IsInRole(Constants.AdminRoleName))
            {
                // Seems we *need* a specific authentication provider. Check if we logged in using one...
                var providers = enforcedProviders.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);

                if (!providers.Any(p => string.Equals(p, authenticatedUser.CredentialUsed.Type, StringComparison.OrdinalIgnoreCase))
                    && !providers.Any(p => string.Equals(CredentialTypes.ExternalPrefix + p, authenticatedUser.CredentialUsed.Type, StringComparison.OrdinalIgnoreCase)))
                {
                    // Challenge authentication using the first required authentication provider
                    challenge = _authService.Challenge(
                        providers.First(),
                        Url.Action("LinkExternalAccount", "Authentication", new { ReturnUrl = returnUrl }));

                    return true;
                }
            }

            challenge = null;
            return false;
        }
            public async Task WillNotSendConfirmationEmailWhenConfirmEmailAddressesIsOff()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        EmailConfirmationToken = "t0k3n"
                    },
                    new Credential());
                var config = Get<ConfigurationService>();
                config.Current = new AppConfiguration()
                {
                    ConfirmEmailAddresses = false
                };
                GetMock<AuthenticationService>()
                    .Setup(x => x.Register("theUsername", "*****@*****.**", It.IsAny<Credential>()))
                    .CompletesWith(authUser);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();

                // Act
                var result = await controller.Register(
                    new LogOnViewModel()
                    {
                        Register = new RegisterViewModel
                        {
                            Username = "******",
                            Password = "******",
                            EmailAddress = "*****@*****.**",
                        }
                    }, "/theReturnUrl", linkingAccount: false);

                // Assert
                GetMock<IMessageService>()
                    .Verify(x => x.SendNewAccountEmail(
                        It.IsAny<MailAddress>(),
                        It.IsAny<string>()), Times.Never());
            }
            public async Task GivenAUser_ItCreatesAnOwinAuthenticationTicketForTheUser()
            {
                // Arrange
                var service = Get<AuthenticationService>();
                var context = Fakes.CreateOwinContext();

                var passwordCred = Fakes.Admin.Credentials.SingleOrDefault(
                    c => String.Equals(c.Type, CredentialTypes.Password.Pbkdf2, StringComparison.OrdinalIgnoreCase));

                var authUser = new AuthenticatedUser(Fakes.Admin, passwordCred);

                // Act
                await service.CreateSessionAsync(context, authUser);

                // Assert
                var principal = context.Authentication.AuthenticationResponseGrant.Principal;
                var id = principal.Identity;
                Assert.NotNull(principal);
                Assert.NotNull(id);
                Assert.Equal(Fakes.Admin.Username, id.Name);
                Assert.Equal(Fakes.Admin.Username, principal.GetClaimOrDefault(ClaimTypes.NameIdentifier));
                Assert.Equal(AuthenticationTypes.LocalUser, id.AuthenticationType);
                Assert.True(principal.IsInRole(Constants.AdminRoleName));
            }
            public async Task GivenExpiredExternalAuth_ItRedirectsBackToLogOnWithExternalAuthExpiredMessage()
            {
                // Arrange
                var authUser = new AuthenticatedUser(new User("theUsername"), new Credential());

                GetMock<AuthenticationService>(); // Force AuthenticationService to be mocked even though it's concrete
                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult());

                // Act
                var result = await controller.Register(
                    new LogOnViewModel()
                    {
                        Register = new RegisterViewModel
                        {
                            Username = "******",
                            EmailAddress = "theEmailAddress",
                        }
                    }, "/theReturnUrl", linkingAccount: true);

                // Assert
                VerifyExternalLinkExpiredResult(controller, result);
                GetMock<AuthenticationService>()
                    .Verify(x => x.CreateSession(It.IsAny<IOwinContext>(), It.IsAny<User>()), Times.Never());
                GetMock<AuthenticationService>()
                    .Verify(x => x.Register("theUsername", "theEmailAddress", It.IsAny<Credential>()), Times.Never());
            }
        public virtual async Task CreateSessionAsync(IOwinContext owinContext, AuthenticatedUser user)
        {
            // Create a claims identity for the session
            ClaimsIdentity identity = CreateIdentity(user.User, AuthenticationTypes.LocalUser);

            // Issue the session token and clean up the external token if present
            owinContext.Authentication.SignIn(identity);
            owinContext.Authentication.SignOut(AuthenticationTypes.External);
            
            // Write an audit record
            await Auditing.SaveAuditRecord(
                new UserAuditRecord(user.User, AuditedUserAction.Login, user.CredentialUsed));
        }
            public async Task GivenValidExternalAuth_ItCreatesAccountAndLinksCredential()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        EmailConfirmationToken = "t0k3n"
                    },
                    new Credential());
                var externalCred = CredentialBuilder.CreateExternalCredential("MicrosoftAccount", "blorg", "Bloog");

                GetMock<AuthenticationService>()
                    .Setup(x => x.Register("theUsername", "theEmailAddress", externalCred))
                    .CompletesWith(authUser);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSession(controller.OwinContext, authUser.User))
                    .Verifiable();
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Simulate the model state error that will be added when doing an external account registration (since password is not present)
                controller.ModelState.AddModelError("Register.Password", "Password is required");

                // Act
                var result = await controller.Register(
                    new LogOnViewModel()
                    {
                        Register = new RegisterViewModel
                        {
                            Username = "******",
                            EmailAddress = "theEmailAddress",
                        }
                    }, "/theReturnUrl", linkingAccount: true);

                // Assert
                GetMock<AuthenticationService>().VerifyAll();

                var expectedAddress = new MailAddress(authUser.User.UnconfirmedEmailAddress, authUser.User.Username);
                GetMock<IMessageService>()
                    .Verify(x => x.SendNewAccountEmail(
                        expectedAddress,
                        "https://nuget.local/account/confirm/theUsername/t0k3n"));

                ResultAssert.IsSafeRedirectTo(result, "/theReturnUrl");
            }