private async Task <bool> ExecutePasswordFlow(IOwinEnvironment context, IClient client, string username, string password, CancellationToken cancellationToken) { var preLoginContext = new PreLoginContext(context) { Login = username }; await _handlers.PreLoginHandler(preLoginContext, cancellationToken); var passwordGrantRequestBuilder = OauthRequests.NewPasswordGrantRequest() .SetLogin(preLoginContext.Login) .SetPassword(password); if (preLoginContext.AccountStore != null) { passwordGrantRequestBuilder.SetAccountStore(preLoginContext.AccountStore); } var passwordGrantRequest = passwordGrantRequestBuilder.Build(); var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var tokenResult = await application.NewPasswordGrantAuthenticator() .AuthenticateAsync(passwordGrantRequest, cancellationToken); var accessToken = await tokenResult.GetAccessTokenAsync(cancellationToken); var account = await accessToken.GetAccountAsync(cancellationToken); var postLoginContext = new PostLoginContext(context, account); await _handlers.PostLoginHandler(postLoginContext, cancellationToken); var sanitizer = new GrantResultResponseSanitizer(); return(await JsonResponse.Ok(context, sanitizer.SanitizeResponseWithRefreshToken(tokenResult)).ConfigureAwait(false)); }
protected override Task <bool> GetJsonAsync(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var viewModelBuilder = new LoginViewModelBuilder(_configuration.Web.Login, _configuration.Providers); var loginViewModel = viewModelBuilder.Build(); return(JsonResponse.Ok(context, loginViewModel)); }
protected override Task <bool> GetJsonAsync(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var viewModelBuilder = new RegisterViewModelBuilder(_configuration.Web.Register); var registerViewModel = viewModelBuilder.Build(); return(JsonResponse.Ok(context, registerViewModel)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var body = await context.Request.GetBodyAsStringAsync(cancellationToken); var model = PostBodyParser.ToModel <RegisterPostModel>(body, bodyContentType, _logger); var formData = Serializer.DeserializeDictionary(body); var allNonEmptyFieldNames = formData.Where(f => !string.IsNullOrEmpty(f.Value.ToString())).Select(f => f.Key).ToList(); var providedCustomFields = new Dictionary <string, object>(); foreach (var item in formData.Where(x => !DefaultFields.Contains(x.Key))) { providedCustomFields.Add(item.Key, item.Value); } var customDataObject = formData.Get <IDictionary <string, object> >("customData"); if (customDataObject != null && customDataObject.Any()) { foreach (var item in customDataObject) { providedCustomFields.Add(item.Key, item.Value); } } var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); var newAccount = await InstantiateLocalAccount( context, model, allNonEmptyFieldNames, providedCustomFields, client, jsonErrorHandler, cancellationToken); if (newAccount == null) { return(true); // Some error occurred and the handler was invoked } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new RegisterExecutor(client, _configuration, _handlers, _logger); var createdAccount = await executor.HandleRegistrationAsync(context, application, newAccount, cancellationToken); await executor.HandlePostRegistrationAsync(context, createdAccount, cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(createdAccount) }; return(await JsonResponse.Ok(context, responseModel)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var executor = new LogoutExecutor(client, _configuration, _handlers, _logger); await executor.HandleLogoutAsync(context, cancellationToken); await JsonResponse.Ok(context); return(true); }
private async Task <bool> ExecuteClientCredentialsFlow(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var basicHeaderParser = new BasicAuthenticationParser(context.Request.Headers.GetString("Authorization"), _logger); if (!basicHeaderParser.IsValid) { await Error.Create <OauthInvalidRequest>(context, cancellationToken); return(true); } var preLoginContext = new PreLoginContext(context) { Login = basicHeaderParser.Username }; await _handlers.PreLoginHandler(preLoginContext, cancellationToken).ConfigureAwait(false); var request = new ClientCredentialsGrantRequest { Id = basicHeaderParser.Username, Secret = basicHeaderParser.Password }; if (preLoginContext.AccountStore != null) { request.AccountStoreHref = preLoginContext.AccountStore.Href; } var application = await client .GetApplicationAsync(_configuration.Application.Href, cancellationToken) .ConfigureAwait(false); IOauthGrantAuthenticationResult tokenResult; try { tokenResult = await application .ExecuteOauthRequestAsync(request, cancellationToken) .ConfigureAwait(false); } // Catch error 10019 (API Authentication failed) catch (ResourceException rex) when(rex.Code == 10019) { return(await Error.Create <OauthInvalidClient>(context, cancellationToken).ConfigureAwait(false)); } var accessToken = await tokenResult.GetAccessTokenAsync(cancellationToken).ConfigureAwait(false); var account = await accessToken.GetAccountAsync(cancellationToken).ConfigureAwait(false); var postLoginContext = new PostLoginContext(context, account); await _handlers.PostLoginHandler(postLoginContext, cancellationToken).ConfigureAwait(false); var sanitizer = new GrantResultResponseSanitizer(); return(await JsonResponse.Ok(context, sanitizer.SanitizeResponseWithoutRefreshToken(tokenResult)).ConfigureAwait(false)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <LoginPostModel>(context, bodyContentType, _logger, cancellationToken); if (model.ProviderData != null) { return(await HandleSocialLogin(context, client, model, cancellationToken)); } var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); bool missingLoginOrPassword = string.IsNullOrEmpty(model.Login) || string.IsNullOrEmpty(model.Password); if (missingLoginOrPassword) { await jsonErrorHandler("Missing login or password.", cancellationToken); return(true); } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new LoginExecutor(client, _configuration, _handlers, _logger); var grantResult = await executor.PasswordGrantAsync( context, application, jsonErrorHandler, model.Login, model.Password, cancellationToken); if (grantResult == null) { return(true); // The error handler was invoked } await executor.HandlePostLoginAsync(context, grantResult, cancellationToken); var token = await grantResult.GetAccessTokenAsync(cancellationToken); var account = await token.GetAccountAsync(cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(account) }; return(await JsonResponse.Ok(context, responseModel)); }
private async Task <bool> ExecuteRefreshFlow(IOwinEnvironment context, IClient client, string refreshToken, CancellationToken cancellationToken) { var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var refreshGrantRequest = OauthRequests.NewRefreshGrantRequest() .SetRefreshToken(refreshToken) .Build(); var tokenResult = await application.NewRefreshGrantAuthenticator() .AuthenticateAsync(refreshGrantRequest, cancellationToken); var sanitizer = new GrantResultResponseSanitizer(); return(await JsonResponse.Ok(context, sanitizer.SanitizeResponseWithRefreshToken(tokenResult)).ConfigureAwait(false)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); try { var model = await PostBodyParser.ToModel <ForgotPasswordPostModel>(context, bodyContentType, _logger, cancellationToken); await application.SendPasswordResetEmailAsync(model.Email, cancellationToken); } catch (Exception ex) { _logger.Error(ex, source: "ForgotRoute.PostJson"); } return(await JsonResponse.Ok(context)); }
protected override async Task <bool> PostAsync( IOwinEnvironment context, IClient client, ContentNegotiationResult acceptContentNegotiationResult, CancellationToken cancellationToken) { var executor = new LogoutExecutor(client, _configuration, _handlers, _logger); await executor.HandleLogoutAsync(context, cancellationToken); if (acceptContentNegotiationResult.ContentType == ContentType.Html) { return(await executor.HandleRedirectAsync(context)); } await JsonResponse.Ok(context); return(true); }
protected override async Task <bool> GetJsonAsync(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var queryString = QueryStringParser.Parse(context.Request.QueryString, _logger); var spToken = queryString.GetString("sptoken"); if (string.IsNullOrEmpty(spToken)) { return(await Error.Create(context, new BadRequest("sptoken parameter not provided."), cancellationToken)); } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); await application.VerifyPasswordResetTokenAsync(spToken, cancellationToken); // Errors are caught in AbstractRouteMiddleware return(await JsonResponse.Ok(context)); }
protected override async Task <bool> GetJsonAsync(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var queryString = QueryStringParser.Parse(context.Request.QueryString, _logger); var spToken = queryString.GetString("sptoken"); if (string.IsNullOrEmpty(spToken)) { return(await Error.Create(context, new BadRequest("sptoken parameter not provided."), cancellationToken)); } var account = await client.VerifyAccountEmailAsync(spToken, cancellationToken); // Errors are caught in AbstractRouteMiddleware var postVerifyEmailContext = new PostVerifyEmailContext(context, account); await _handlers.PostVerifyEmailHandler(postVerifyEmailContext, cancellationToken); return(await JsonResponse.Ok(context)); }
protected override async Task <bool> GetJsonAsync(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { Caching.AddDoNotCacheHeaders(context); var stormpathAccount = context.Request[OwinKeys.StormpathUser] as IAccount; var expansionOptions = _configuration.Web.Me.Expand; if (expansionOptions.Any(e => e.Value)) { stormpathAccount = await GetExpandedAccount(stormpathAccount.Href, client, expansionOptions, cancellationToken); } var responseModel = new { account = await SanitizeExpandedAccount(stormpathAccount, expansionOptions, cancellationToken) }; return(await JsonResponse.Ok(context, responseModel)); }
private async Task <bool> ExecutePasswordFlow(IOwinEnvironment context, IClient client, string username, string password, CancellationToken cancellationToken) { var executor = new LoginExecutor(client, _configuration, _handlers, _logger); var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); var grantResult = await executor.PasswordGrantAsync( context, application, jsonErrorHandler, username, password, cancellationToken); await executor.HandlePostLoginAsync(context, grantResult, cancellationToken); var sanitizer = new GrantResultResponseSanitizer(); return(await JsonResponse.Ok(context, sanitizer.SanitizeResponseWithRefreshToken(grantResult)).ConfigureAwait(false)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <ChangePasswordPostModel>(context, bodyContentType, _logger, cancellationToken); var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var account = await application.VerifyPasswordResetTokenAsync(model.SpToken, cancellationToken); // Errors are caught in AbstractRouteMiddleware var preChangePasswordContext = new PreChangePasswordContext(context, account); await _handlers.PreChangePasswordHandler(preChangePasswordContext, cancellationToken); await application.ResetPasswordAsync(model.SpToken, model.Password, cancellationToken); var postChangePasswordContext = new PostChangePasswordContext(context, account); await _handlers.PostChangePasswordHandler(postChangePasswordContext, cancellationToken); // TODO autologin return(await JsonResponse.Ok(context)); }
private async Task <bool> ExecuteClientCredentialsFlow(IOwinEnvironment context, IClient client, CancellationToken cancellationToken) { var jsonErrorHandler = new Func <AbstractError, CancellationToken, Task>((err, ct) => Error.Create(context, err, ct)); var basicHeaderParser = new BasicAuthenticationParser(context.Request.Headers.GetString("Authorization"), _logger); if (!basicHeaderParser.IsValid) { await jsonErrorHandler(new OauthInvalidRequest(), cancellationToken); return(true); } var executor = new LoginExecutor(client, _configuration, _handlers, _logger); var application = await client .GetApplicationAsync(_configuration.Application.Href, cancellationToken) .ConfigureAwait(false); var tokenResult = await executor.ClientCredentialsGrantAsync( context, application, jsonErrorHandler, basicHeaderParser.Username, basicHeaderParser.Password, cancellationToken); if (tokenResult == null) { return(true); // Some error occurred and the handler was invoked } await executor.HandlePostLoginAsync(context, tokenResult, cancellationToken); var sanitizer = new GrantResultResponseSanitizer(); return(await JsonResponse.Ok(context, sanitizer.SanitizeResponseWithoutRefreshToken(tokenResult)).ConfigureAwait(false)); }
protected JsonResult JsonSuccess(object data) { var result = JsonResponse.Ok(data); return(Json(result)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var model = await PostBodyParser.ToModel <VerifyEmailPostModel>(context, bodyContentType, _logger, cancellationToken); var jsonSuccessHandler = new Func <CancellationToken, Task <bool> >(ct => JsonResponse.Ok(context)); return(await ResendVerification( email : model.Email, client : client, environment : context, errorHandler : null, // Errors are caught in AbstractRouteMiddleware successHandler : jsonSuccessHandler, cancellationToken : cancellationToken)); }
protected override async Task <bool> PostJsonAsync(IOwinEnvironment context, IClient client, ContentType bodyContentType, CancellationToken cancellationToken) { var body = await context.Request.GetBodyAsStringAsync(cancellationToken); var model = PostBodyParser.ToModel <RegisterPostModel>(body, bodyContentType, _logger); var formData = Serializer.DeserializeDictionary(body); var sanitizedFormData = new Dictionary <string, string>(); var customFields = new Dictionary <string, string>(); // Look for a root object called "customData" var customDataObject = formData.Get <IDictionary <string, object> >("customData"); if (customDataObject != null && customDataObject.Any()) { foreach (var field in customDataObject) { TryAdd(formData, field.Key, field.Value); } } foreach (var field in formData) { // The key "customData" is a special case, see above if (field.Key.Equals("customData", StringComparison.Ordinal)) { continue; } if (!DefaultFields.Contains(field.Key)) { TryAdd(customFields, field.Key, field.Value?.ToString()); } TryAdd(sanitizedFormData, field.Key, field.Value?.ToString()); } var allNonEmptyFieldNames = sanitizedFormData .Where(f => !string.IsNullOrEmpty(f.Value.ToString())) .Select(f => f.Key) .Distinct() .ToArray(); var jsonErrorHandler = new Func <string, CancellationToken, Task>((message, ct) => Error.Create(context, new BadRequest(message), ct)); var newAccount = await InstantiateLocalAccount( context, model, allNonEmptyFieldNames, customFields, client, jsonErrorHandler, cancellationToken); if (newAccount == null) { return(true); // Some error occurred and the handler was invoked } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var executor = new RegisterExecutor(client, _configuration, _handlers, _logger); var formDataForHandler = sanitizedFormData .ToDictionary(kv => kv.Key, kv => kv.Value?.ToString()); var createdAccount = await executor.HandleRegistrationAsync( context, application, formDataForHandler, newAccount, jsonErrorHandler, cancellationToken); if (createdAccount == null) { return(true); // Some error occurred and the handler was invoked } await executor.HandlePostRegistrationAsync(context, createdAccount, cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(createdAccount) }; return(await JsonResponse.Ok(context, responseModel)); }
private async Task <bool> HandleSocialLogin(IOwinEnvironment context, IClient client, LoginPostModel model, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(model.ProviderData.ProviderId)) { return(await Error.Create(context, new BadRequest("No provider specified"), cancellationToken)); } var application = await client.GetApplicationAsync(_configuration.Application.Href, cancellationToken); var socialExecutor = new SocialExecutor(client, _configuration, _handlers, _logger); try { IProviderAccountRequest providerRequest; switch (model.ProviderData.ProviderId) { case "facebook": { providerRequest = client.Providers() .Facebook() .Account() .SetAccessToken(model.ProviderData.AccessToken) .Build(); break; } case "google": { providerRequest = client.Providers() .Google() .Account() .SetCode(model.ProviderData.Code) .Build(); break; } case "github": { providerRequest = client.Providers() .Github() .Account() .SetAccessToken(model.ProviderData.AccessToken) .Build(); break; } case "linkedin": { providerRequest = client.Providers() .LinkedIn() .Account() .SetAccessToken(model.ProviderData.AccessToken) .Build(); break; } default: providerRequest = null; break; } if (providerRequest == null) { return(await Error.Create(context, new BadRequest($"Unknown provider '{model.ProviderData.ProviderId}'"), cancellationToken)); } var loginResult = await socialExecutor.LoginWithProviderRequestAsync(context, providerRequest, cancellationToken); await socialExecutor.HandleLoginResultAsync( context, application, loginResult, cancellationToken); var sanitizer = new AccountResponseSanitizer(); var responseModel = new { account = sanitizer.Sanitize(loginResult.Account) }; return(await JsonResponse.Ok(context, responseModel)); } catch (ResourceException rex) { // TODO improve error logging (include request id, etc) _logger.Error(rex.DeveloperMessage, source: nameof(HandleSocialLogin)); return(await Error.Create(context, new BadRequest("An error occurred while processing the login"), cancellationToken)); } catch (Exception ex) { _logger.Error(ex, source: nameof(HandleSocialLogin)); return(await Error.Create(context, new BadRequest("An error occurred while processing the login"), cancellationToken)); } }