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); } }
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); }