public LoginActionResult(IViewService viewSvc, LoginViewModel model, SignInMessage message)
     : base(async () => await viewSvc.Login(model, message))
 {
     if (viewSvc == null) throw new ArgumentNullException("viewSvc");
     if (model == null) throw new ArgumentNullException("model");
     if (message == null) throw new ArgumentNullException("message");
 }
        public async Task<CustomGrantValidationResult> ValidateAsync(ValidatedTokenRequest request)
        {
            var legacyAccountStoreType = request.Raw.Get("account_store");
            var id = request.Raw.Get("legacy_id");
            var secret = request.Raw.Get("legacy_secret");

            if (string.IsNullOrWhiteSpace(legacyAccountStoreType) ||
                string.IsNullOrWhiteSpace(id) ||
                string.IsNullOrWhiteSpace(secret))
            {
                Logger.Error("malformed request");
                return null;
            }

            var message = new SignInMessage { Tenant = legacyAccountStoreType };
            var context = new LocalAuthenticationContext
            {
                UserName = id, Password = secret,
                SignInMessage = message
            };
            await _users.AuthenticateLocalAsync(context);

            var result = context.AuthenticateResult;
            if (result.IsError)
            {
                Logger.Error("authentication failed");
                return new CustomGrantValidationResult("Authentication failed.");
            }

            return new CustomGrantValidationResult(
                result.User.GetSubjectId(),
                "custom",
                result.User.Claims);
        }
 /// <summary>
 /// Gets the currently running client app to put it's name in the login page
 /// </summary>
 /// <param name="model"></param>
 /// <param name="message"></param>
 /// <returns></returns>
 public async Task<Stream> Login(LoginViewModel model, SignInMessage message)
 {
     var client = await clientStore.FindClientByIdAsync(message.ClientId);
     var name = client != null ? client.ClientName : null;
     return await Render(model, "login", name);
     
 }
 public AuthorizeInteractionResponseGenerator(IdentityServerOptions options, IConsentService consent, IUserService users, ILocalizationService localizationService)
 {
     _signIn = new SignInMessage();
     _options = options;
     _consent = consent;
     _users = users;
     _localizationService = localizationService;
 }
        public LoginResult(IDictionary<string, object> env, SignInMessage message)
        {
            if (env == null) throw new ArgumentNullException("env");
            if (message == null) throw new ArgumentNullException("message");

            this.env = env;
            this.message = message;
        }
        private HttpResponseMessage GetLoginPage(SignInMessage msg = null)
        {
            msg = msg ?? new SignInMessage() { ReturnUrl = Url("authorize") };
            if (msg.ClientId == null) msg.ClientId = TestClients.Get().First().ClientId;

            SignInId = WriteMessageToCookie(msg);

            var resp = Get(Constants.RoutePaths.Login + "?signin=" + SignInId);
            ProcessXsrf(resp);
            return resp;
        }
        void Login(bool setCookie = true)
        {
            var msg = new SignInMessage() { ReturnUrl = Url("authorize") };
            var signInId = WriteMessageToCookie(msg);
            var url = Constants.RoutePaths.Login + "?signin=" + signInId;
            var resp = Get(url);
            ProcessXsrf(resp);

            if (setCookie)
            {
                resp = PostForm(url, new LoginCredentials { Username = "******", Password = "******" });
                client.SetCookies(resp.GetCookies());
            }
        }
        async Task<bool> IsLocalLoginAllowedForClient(SignInMessage message)
        {
            if (message != null && message.ClientId.IsPresent())
            {
                var client = await clientStore.FindClientByIdAsync(message.ClientId);
                if (client != null)
                {
                    return client.EnableLocalLogin;
                }
            }

            return true;
        }
        private Uri GetRedirectUrl(SignInMessage signInMessage, AuthenticateResult authResult)
        {
            if (signInMessage == null) throw new ArgumentNullException("signInMessage");
            if (authResult == null) throw new ArgumentNullException("authResult");

            if (authResult.IsPartialSignIn)
            {
                var path = authResult.PartialSignInRedirectPath;
                if (path.StartsWith("~/"))
                {
                    path = path.Substring(2);
                    path = Request.GetIdentityServerBaseUrl() + path;
                }
                var host = new Uri(context.GetIdentityServerHost());
                return new Uri(host, path);
            }
            else
            {
                return new Uri(signInMessage.ReturnUrl);
            }
        }
Beispiel #10
0
		public async Task<Stream> Login (LoginViewModel model, SignInMessage message)
		{
			return await Render (model, "Login");
		}
        IHttpActionResult RedirectToLogin(SignInValidationResult result)
        {
            Uri publicRequestUri = GetPublicRequestUri();

            var message = new SignInMessage();
            message.ReturnUrl = publicRequestUri.ToString();

            if (!String.IsNullOrWhiteSpace(result.HomeRealm))
            {
                message.IdP = result.HomeRealm;
            }

            if (!String.IsNullOrWhiteSpace(result.Federation))
            {
                message.AcrValues = new[] { result.Federation };
            }
            
            var env = Request.GetOwinEnvironment();
            var url = env.CreateSignInRequest(message);
            
            return Redirect(url);
        }
 private async Task RaiseSuccessfulResourceOwnerAuthenticationEventAsync(string userName, string subjectId, SignInMessage signInMessage)
 {
     await _events.RaiseSuccessfulResourceOwnerFlowAuthenticationEventAsync(userName, subjectId, signInMessage);
 }
 /// <summary>
 /// Loads the HTML for the login page.
 /// </summary>
 /// <param name="model">The model.</param>
 /// <param name="message">The message.</param>
 /// <returns>
 /// Stream for the HTML
 /// </returns>
 public virtual Task<Stream> Login(LoginViewModel model, SignInMessage message)
 {
     return Render(model, LoginView);
 }
        public void LoginExternalCallback_UserIsAnonymous_NoSubjectIsPassedToUserService()
        {
            var msg = new SignInMessage();
            msg.IdP = "Google";
            msg.ReturnUrl = Url("authorize");
            var resp1 = GetLoginPage(msg);

            var sub = new Claim(Constants.ClaimTypes.Subject, "123", ClaimValueTypes.String, "Google");
            SignInIdentity = new ClaimsIdentity(new Claim[] { sub }, Constants.ExternalAuthenticationType);
            var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
            client.SetCookies(resp2.GetCookies());

            Get(Constants.RoutePaths.LoginExternalCallback);

            mockUserService.Verify(x => x.AuthenticateExternalAsync(It.IsAny<ExternalAuthenticationContext>()));
        }
        public void LoginExternalCallback_UserServiceReturnsNull_ShowError()
        {
            mockUserService.Setup(x => x.AuthenticateExternalAsync(It.IsAny<ExternalAuthenticationContext>()))
                .Returns(Task.FromResult((AuthenticateResult)null));

            var msg = new SignInMessage();
            msg.IdP = "Google";
            msg.ReturnUrl = Url("authorize");
            var resp1 = GetLoginPage(msg);

            var sub = new Claim(Constants.ClaimTypes.Subject, "123", ClaimValueTypes.String, "Google");
            SignInIdentity = new ClaimsIdentity(new Claim[] { sub }, Constants.ExternalAuthenticationType);
            var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
            client.SetCookies(resp2.GetCookies());

            var resp3 = Get(Constants.RoutePaths.LoginExternalCallback);
            resp3.AssertPage("login");
            var model = resp3.GetModel<LoginViewModel>();
            model.ErrorMessage.Should().Be(Messages.NoMatchingExternalAccount);
        }
        public void LoginExternalCallback_WithValidSubjectClaim_RedirectsToAuthorizeEndpoint()
        {
            var msg = new SignInMessage();
            msg.IdP = "Google";
            msg.ReturnUrl = Url("authorize");
            var resp1 = GetLoginPage(msg);

            var sub = new Claim(Constants.ClaimTypes.Subject, "123", ClaimValueTypes.String, "Google");
            SignInIdentity = new ClaimsIdentity(new Claim[] { sub }, Constants.ExternalAuthenticationType);
            var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
            client.SetCookies(resp2.GetCookies());

            var resp3 = Get(Constants.RoutePaths.LoginExternalCallback);
            resp3.StatusCode.Should().Be(HttpStatusCode.Found);
            resp3.Headers.Location.AbsoluteUri.Should().Be(Url("authorize"));
        }
        public void LoginExternalCallback_WithValidNameIDClaim_IssuesAuthenticationCookie()
        {
            var msg = new SignInMessage();
            msg.IdP = "Google";
            msg.ReturnUrl = Url("authorize");
            var resp1 = GetLoginPage(msg);

            var sub = new Claim(ClaimTypes.NameIdentifier, "123", ClaimValueTypes.String, "Google");
            SignInIdentity = new ClaimsIdentity(new Claim[] { sub }, Constants.ExternalAuthenticationType);
            var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
            client.SetCookies(resp2.GetCookies());

            var resp3 = Get(Constants.RoutePaths.LoginExternalCallback);
            resp3.AssertCookie(Constants.PrimaryAuthenticationType);
        }
        public void LoginExternalCallback_WithoutSubjectOrNameIdClaims_RendersLoginPageWithError()
        {
            var msg = new SignInMessage();
            msg.IdP = "Google";
            var resp1 = GetLoginPage(msg);

            SignInIdentity = new ClaimsIdentity(new Claim[]{new Claim("foo", "bar")}, Constants.ExternalAuthenticationType);
            var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
            client.SetCookies(resp2.GetCookies());
            
            var resp3 = Get(Constants.RoutePaths.LoginExternalCallback);
            resp3.AssertPage("login");
            var model = resp3.GetModel<LoginViewModel>();
            model.ErrorMessage.Should().Be(Messages.NoMatchingExternalAccount);
        }
 public void LoginExternalCallback_WithoutExternalCookie_RendersErrorPage()
 {
     var msg = new SignInMessage();
     msg.IdP = "Google";
     var resp1 = GetLoginPage(msg);
     var resp2 = client.GetAsync(resp1.Headers.Location.AbsoluteUri).Result;
     var resp3 = Get(Constants.RoutePaths.LoginExternalCallback);
     resp3.AssertPage("error");
 }
        private async Task<IHttpActionResult> RenderLoginPage(SignInMessage message, string signInMessageId, string errorMessage = null, string username = null, bool rememberMe = false)
        {
            if (message == null) throw new ArgumentNullException("message");

            username = GetUserNameForLoginPage(message, username);

            var isLocalLoginAllowedForClient = await IsLocalLoginAllowedForClient(message);
            var isLocalLoginAllowed = isLocalLoginAllowedForClient && options.AuthenticationOptions.EnableLocalLogin;

            var idpRestrictions = await clientStore.GetIdentityProviderRestrictionsAsync(message.ClientId);
            var providers = context.GetExternalAuthenticationProviders(idpRestrictions);
            var providerLinks = context.GetLinksFromProviders(providers, signInMessageId);
            var visibleLinks = providerLinks.FilterHiddenLinks();
            var client = await clientStore.FindClientByIdAsync(message.ClientId);

            if (errorMessage != null)
            {
                Logger.InfoFormat("rendering login page with error message: {0}", errorMessage);
            }
            else
            {
                if (isLocalLoginAllowed == false)
                {
                    if (options.AuthenticationOptions.EnableLocalLogin)
                    {
                        Logger.Info("local login disabled");
                    }
                    if (isLocalLoginAllowedForClient)
                    {
                        Logger.Info("local login disabled for the client");
                    }

                    string url = null;

                    if (!providerLinks.Any())
                    {
                        Logger.Info("no providers registered for client");
                        return RenderErrorPage();
                    }
                    else if (providerLinks.Count() == 1)
                    {
                        Logger.Info("only one provider for client");
                        url = providerLinks.First().Href;
                    }
                    else if (visibleLinks.Count() == 1)
                    {
                        Logger.Info("only one visible provider");
                        url = visibleLinks.First().Href;
                    }

                    if (url.IsPresent())
                    {
                        Logger.InfoFormat("redirecting to provider URL: {0}", url);
                        return Redirect(url);
                    }
                }

                Logger.Info("rendering login page");
            }

            var loginPageLinks = options.AuthenticationOptions.LoginPageLinks.Render(Request.GetIdentityServerBaseUrl(), signInMessageId);

            var loginModel = new LoginViewModel
            {
                RequestId = context.GetRequestId(),
                SiteName = options.SiteName,
                SiteUrl = Request.GetIdentityServerBaseUrl(),
                ExternalProviders = visibleLinks,
                AdditionalLinks = loginPageLinks,
                ErrorMessage = errorMessage,
                LoginUrl = isLocalLoginAllowed ? Url.Route(Constants.RouteNames.Login, new { signin = signInMessageId }) : null,
                AllowRememberMe = options.AuthenticationOptions.CookieOptions.AllowRememberMe,
                RememberMe = options.AuthenticationOptions.CookieOptions.AllowRememberMe && rememberMe,
                CurrentUser = context.GetCurrentUserDisplayName(),
                LogoutUrl = context.GetIdentityServerLogoutUrl(),
                AntiForgery = antiForgeryToken.GetAntiForgeryToken(),
                Username = username,
                ClientName = client != null ? client.ClientName : null,
                ClientUrl = client != null ? client.ClientUri : null,
                ClientLogoUrl = client != null ? client.LogoUri : null
            };

            return new LoginActionResult(viewService, loginModel, message);
        }
        private string GetUserNameForLoginPage(SignInMessage message, string username)
        {
            if (username.IsMissing() && message.LoginHint.IsPresent())
            {
                if (options.AuthenticationOptions.EnableLoginHint)
                {
                    Logger.InfoFormat("Using LoginHint for username: {0}", message.LoginHint);
                    username = message.LoginHint;
                }
                else
                {
                    Logger.Warn("Not using LoginHint because EnableLoginHint is false");
                }
            }

            var lastUsernameCookieValue = lastUserNameCookie.GetValue();
            if (username.IsMissing() && lastUsernameCookieValue.IsPresent())
            {
                Logger.InfoFormat("Using LastUserNameCookie value for username: {0}", lastUsernameCookieValue);
                username = lastUsernameCookieValue;
            }
            return username;
        }
        IHttpActionResult RedirectToLogin(SignInMessage message, NameValueCollection parameters)
        {
            message = message ?? new SignInMessage();

            var path = Url.Route(Constants.RouteNames.Oidc.Authorize, null).AddQueryString(parameters.ToQueryString());
            var host = new Uri(Request.GetOwinEnvironment().GetIdentityServerHost());
            var url = new Uri(host, path);
            message.ReturnUrl = url.AbsoluteUri;

            return new LoginResult(Request.GetOwinContext().Environment, message);
        }
        private async Task<TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters)
        {
            Logger.Info("Start password token request validation");

            // if we've disabled local authentication, then fail
            if (_options.AuthenticationOptions.EnableLocalLogin == false ||
                _validatedRequest.Client.EnableLocalLogin == false)
            {
                LogError("EnableLocalLogin is disabled, failing with UnsupportedGrantType");
                return Invalid(Constants.TokenErrors.UnsupportedGrantType);
            }

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (_validatedRequest.Client.Flow != Flows.ResourceOwner)
            {
                LogError("Client not authorized for resource owner flow");
                return Invalid(Constants.TokenErrors.UnauthorizedClient);
            }

            /////////////////////////////////////////////
            // check if client is allowed to request scopes
            /////////////////////////////////////////////
            if (!(await ValidateRequestedScopesAsync(parameters)))
            {
                LogError("Invalid scopes.");
                return Invalid(Constants.TokenErrors.InvalidScope);
            }

            /////////////////////////////////////////////
            // check resource owner credentials
            /////////////////////////////////////////////
            var userName = parameters.Get(Constants.TokenRequest.UserName);
            var password = parameters.Get(Constants.TokenRequest.Password);

            if (userName.IsMissing() || password.IsMissing())
            {
                LogError("Username or password missing.");
                return Invalid(Constants.TokenErrors.InvalidGrant);
            }

            if (userName.Length > _options.InputLengthRestrictions.UserName ||
                password.Length > _options.InputLengthRestrictions.Password)
            {
                LogError("Username or password too long.");
                return Invalid(Constants.TokenErrors.InvalidGrant);
            }

            _validatedRequest.UserName = userName;

            /////////////////////////////////////////////
            // check optional parameters and populate SignInMessage
            /////////////////////////////////////////////
            var signInMessage = new SignInMessage();

            // pass through client_id
            signInMessage.ClientId = _validatedRequest.Client.ClientId;

            // process acr values
            var acr = parameters.Get(Constants.AuthorizeRequest.AcrValues);
            if (acr.IsPresent())
            {
                if (acr.Length > _options.InputLengthRestrictions.AcrValues)
                {
                    LogError("Acr values too long.");
                    return Invalid(Constants.TokenErrors.InvalidRequest);
                }

                var acrValues = acr.FromSpaceSeparatedString().Distinct().ToList();

                // look for well-known acr value -- idp
                var idp = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.HomeRealm));
                if (idp.IsPresent())
                {
                    signInMessage.IdP = idp.Substring(Constants.KnownAcrValues.HomeRealm.Length);
                    acrValues.Remove(idp);
                }

                // look for well-known acr value -- tenant
                var tenant = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.Tenant));
                if (tenant.IsPresent())
                {
                    signInMessage.Tenant = tenant.Substring(Constants.KnownAcrValues.Tenant.Length);
                    acrValues.Remove(tenant);
                }

                // pass through any remaining acr values
                if (acrValues.Any())
                {
                    signInMessage.AcrValues = acrValues;
                }
            }

            _validatedRequest.SignInMessage = signInMessage;

            /////////////////////////////////////////////
            // authenticate user
            /////////////////////////////////////////////
            var authenticationContext = new LocalAuthenticationContext
            {
                UserName = userName,
                Password = password,
                SignInMessage = signInMessage
            };

            await _users.AuthenticateLocalAsync(authenticationContext);
            var authnResult = authenticationContext.AuthenticateResult;

            if (authnResult == null || authnResult.IsError || authnResult.IsPartialSignIn)
            {
                var error = Resources.Messages.InvalidUsernameOrPassword;
                if (authnResult != null && authnResult.IsError)
                {
                    error = authnResult.ErrorMessage;
                }
                if (authnResult != null && authnResult.IsPartialSignIn)
                {
                    error = "Partial signin returned from AuthenticateLocalAsync";
                }
                LogError("User authentication failed: " + error);
                await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, signInMessage, error);

                if (authnResult != null)
                {
                    return Invalid(Constants.TokenErrors.InvalidGrant, authnResult.ErrorMessage);
                }

                return Invalid(Constants.TokenErrors.InvalidGrant);
            }

            _validatedRequest.UserName = userName;
            _validatedRequest.Subject = authnResult.User;

            await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, authnResult.User.GetSubjectId(), signInMessage);
            Logger.Info("Password token request validation success.");
            return Valid();
        }
        /// <summary>
        /// Creates and writes the signin cookie to the response and returns the associated URL to the login page.
        /// </summary>
        /// <param name="env">The OWIN environment.</param>
        /// <param name="message">The signin message.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">
        /// env
        /// or
        /// message
        /// </exception>
        public static string CreateSignInRequest(this IDictionary<string, object> env, SignInMessage message)
        {
            if (env == null) throw new ArgumentNullException("env");
            if (message == null) throw new ArgumentNullException("message");

            // if there's no return url, then use current request's URL
            if (message.ReturnUrl.IsMissing())
            {
                var ctx = new OwinContext(env);
                message.ReturnUrl = ctx.Request.Uri.AbsoluteUri;
            }
            if (message.ReturnUrl.StartsWith("~/"))
            {
                message.ReturnUrl = message.ReturnUrl.Substring(1);
            }
            if (message.ReturnUrl.StartsWith("/"))
            {
                message.ReturnUrl = env.GetIdentityServerBaseUrl().RemoveTrailingSlash() + message.ReturnUrl;
            }

            var options = env.ResolveDependency<IdentityServerOptions>();
            var cookie = new MessageCookie<SignInMessage>(env, options);
            var id = cookie.Write(message);

            var url = env.GetIdentityServerBaseUrl() + Constants.RoutePaths.Login;
            var uri = new Uri(url.AddQueryString("signin=" + id));

            return uri.AbsoluteUri;
        }
 private async Task RaiseFailedResourceOwnerAuthenticationEventAsync(string userName, SignInMessage signInMessage, string error)
 {
     await _events.RaiseFailedResourceOwnerFlowAuthenticationEventAsync(userName, signInMessage, error);
 }
        public void GetLoginExternal_ClientDoesAllowsProvider_RedirectsToProvider()
        {
            var clientApp = clients.First();
            clientApp.IdentityProviderRestrictions = new List<string> { "Google" };

            var msg = new SignInMessage();
            msg.IdP = "Google";
            msg.ClientId = clientApp.ClientId;

            var resp = GetLoginPage(msg);
            resp.StatusCode.Should().Be(HttpStatusCode.Found);
            resp.Headers.Location.AbsoluteUri.StartsWith("https://accounts.google.com").Should().BeTrue();
        }
		public Task<Stream> Login(LoginViewModel model, SignInMessage message)
		{
			return Task.FromResult(RunTemplate("login", model, message.ClientId, message.Tenant));
		}
        private async Task<IHttpActionResult> SignInAndRedirectAsync(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool? rememberMe = null)
        {
            var postAuthenActionResult = await PostAuthenticateAsync(signInMessage, authResult);
            if (postAuthenActionResult != null)
            {
                if (postAuthenActionResult.Item1 != null)
                {
                    return postAuthenActionResult.Item1;
                }

                if (postAuthenActionResult.Item2 != null)
                {
                    authResult = postAuthenActionResult.Item2;
                }
            }

            ClearAuthenticationCookiesForNewSignIn(authResult);
            IssueAuthenticationCookie(signInMessageId, authResult, rememberMe);

            var redirectUrl = GetRedirectUrl(signInMessage, authResult);
            Logger.InfoFormat("redirecting to: {0}", redirectUrl);
            return Redirect(redirectUrl);
        }
        private IHttpActionResult RedirectToLogin()
        {
            var message = new SignInMessage();

            var path = Url.Route(Constants.RouteNames.ClientPermissions, null);
            var host = new Uri(Request.GetOwinEnvironment().GetIdentityServerHost());
            var url = new Uri(host, path);
            message.ReturnUrl = url.AbsoluteUri;
            return new LoginResult(Request.GetOwinContext().Environment, message);
        }
        private async Task<Tuple<IHttpActionResult, AuthenticateResult>> PostAuthenticateAsync(SignInMessage signInMessage, AuthenticateResult result)
        {
            if (result.IsPartialSignIn == false)
            {
                Logger.Info("Calling PostAuthenticateAsync on the user service");

                var ctx = new PostAuthenticationContext
                {
                    SignInMessage = signInMessage,
                    AuthenticateResult = result
                };
                await userService.PostAuthenticateAsync(ctx);

                var authResult = ctx.AuthenticateResult;
                if (authResult == null)
                {
                    Logger.Error("user service PostAuthenticateAsync returned a null AuthenticateResult");
                    return new Tuple<IHttpActionResult,AuthenticateResult>(RenderErrorPage(), null);
                }

                if (authResult.IsError)
                {
                    Logger.WarnFormat("user service PostAuthenticateAsync returned an error message: {0}", authResult.ErrorMessage);
                    return new Tuple<IHttpActionResult, AuthenticateResult>(RenderErrorPage(authResult.ErrorMessage), null);
                }

                if (result != authResult)
                {
                    result = authResult;
                    Logger.Info("user service PostAuthenticateAsync returned a different AuthenticateResult");
                }
            }
            
            return new Tuple<IHttpActionResult, AuthenticateResult>(null, result);
        }