protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.TryGetValue("Authorization", out var headerValue)) { Logger.LogInformation("Missing authorization header."); return(AuthenticateResult.Fail("Missing authorization header.")); } if (!AuthenticationHeaderValue.TryParse(headerValue, out var authHeader)) { Logger.LogInformation("Invalid authorization header."); return(AuthenticateResult.Fail("Invalid authorization header.")); } var jwt = authHeader.ToString().Replace("Bearer ", "").Trim(); if (!_jwtService.TryDecode(jwt, out var decodedClaims)) { return(AuthenticateResult.Fail("Invalid jwt token")); } if (!decodedClaims.ContainsKey("id") || !decodedClaims.ContainsKey("access_token") || !await _jwtClaimValidator.ValidateAsync(decodedClaims)) { return(AuthenticateResult.Fail("Invalid jwt token")); } var claims = new[] { new Claim(ClaimTypes.NameIdentifier, decodedClaims["id"]), new Claim(TheIdentityHubClaimTypes.AccessToken, decodedClaims["access_token"]), }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!_httpContextAccessor.HttpContext.Request.Headers.ContainsKey(AuthorizationHeaderName)) { return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers[AuthorizationHeaderName], out AuthenticationHeaderValue headerValue)) { return(AuthenticateResult.NoResult()); } if (headerValue.Scheme != OpaqueTokenDefaults.AuthenticationScheme) { return(AuthenticateResult.NoResult()); } var tokenText = headerValue.Parameter; var token = await _context.AccessTokens.Include(at => at.User).FirstOrDefaultAsync(at => at.Id == tokenText); if (token == null || token.Created.AddSeconds(token.Ttl) < DateTime.UtcNow) { return(AuthenticateResult.NoResult()); } var claims = new [] { new Claim(ClaimTypes.Name, token.User.Username), new Claim(CustomClaimTypes.TokenId, token.Id), new Claim(ClaimTypes.Role, "ExampleRole"), }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
protected async override Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey("Authorization")) { return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out AuthenticationHeaderValue headerValue)) { return(AuthenticateResult.NoResult()); } if (!"Bearer".Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.NoResult()); } var idToken = headerValue.Parameter; var principal = await this.googleAccountService.CreateUserFromIdToken(idToken, this.Scheme.Name); if (principal == null) { return(AuthenticateResult.Fail("Invalid google identity token")); } return(AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name))); }
/// <summary> /// Handle authentication /// </summary> /// <returns></returns> protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out var authenticationHeaderValue)) { var(name, pass) = authenticationHeaderValue.Parameter.AuthorizationParameterToBasicAuth(); if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) { return(AuthenticateResult.NoResult()); } var userAuthInfo = await UserManager.AuthenticateAsync(name, pass); if (userAuthInfo == null) { return(AuthenticateResult.Fail($"Name={name} is not found.")); } var identity = new ClaimsIdentity(userAuthInfo.Select(x => new Claim(x.Key, x.Value)), BasicAuthenticationConstants.Basic); return(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(identity), BasicAuthenticationConstants.Basic))); } return(AuthenticateResult.NoResult()); }
/// <summary>Authentication behavior.</summary> /// <returns>The <see cref="T:Microsoft.AspNetCore.Authentication.AuthenticateResult" /> result.</returns> public async Task <AuthenticateResult> AuthenticateAsync() { var authHeader = this.context.Request.Headers["Authorization"]; if (AuthenticationHeaderValue.TryParse(authHeader, out var authValue)) { if (authValue.Scheme.Equals("token", StringComparison.InvariantCultureIgnoreCase)) { var token = authValue.Parameter; return(await this.UserTokenVerify(token)); } throw new ApplicationException("unsupport"); } else if (this.context.Request.Cookies.TryGetValue("token", out string token)) { return(await this.UserTokenVerify(token)); } else { return(AuthenticateResult.Fail("need token")); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey("Authorization")) { return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out AuthenticationHeaderValue headerValue)) { return(AuthenticateResult.NoResult()); } if (headerValue.Scheme != Options.Scheme) { return(AuthenticateResult.NoResult()); } var apiKey = headerValue.Parameter; var application = _applicationsRepository.GetByApiKey(apiKey); if (application != null) { var claims = new List <Claim>() { new Claim("Name", application.Name), }; var identity = new ClaimsIdentity(claims, Options.AuthenticationType); var principle = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principle, Options.Scheme); return(AuthenticateResult.Success(ticket)); } return(AuthenticateResult.Fail("Invalid api key")); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey(AuthorizationHeaderName)) { //Authorization header not in request return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers[AuthorizationHeaderName], out AuthenticationHeaderValue headerValue)) { //Invalid Authorization header return(AuthenticateResult.NoResult()); } if (!Options.Scheme.Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { //Not Basic authentication header return(AuthenticateResult.NoResult()); } var validUser = await _authenticationService.GetClaimsForKeyAsync(headerValue.Parameter); if (validUser == null) { return(AuthenticateResult.Fail("Invalid key")); } var claims = new List <Claim>(validUser); claims.Add(new Claim(ClaimTypes.Role, Options.Realm)); var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
protected async override Task <AuthenticateResult> HandleAuthenticateAsync() { if (!AuthenticationHeaderValue.TryParse(Request.Headers[HeaderNames.Authorization], out var authValue)) { return(AuthenticateResult.NoResult()); } if (!authValue.Scheme.Equals(Scheme.Name, StringComparison.InvariantCultureIgnoreCase)) { return(AuthenticateResult.NoResult()); } var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authValue.Parameter ?? string.Empty)) .Split(':', 2); if (credentials.Length != 2) { return(AuthenticateResult.Fail("Basic token is malformed")); } var user = await signInManager.UserManager.FindByNameAsync(credentials[0]); if (user is null) { return(AuthenticateResult.Fail("Username or password is incorrect")); } if (!await signInManager.UserManager.CheckPasswordAsync(user, credentials[1])) { return(AuthenticateResult.Fail("Username or password is incorrect")); } var ticket = new AuthenticationTicket(await signInManager.ClaimsFactory.CreateAsync(user), Scheme.Name); return(AuthenticateResult.Success(ticket)); }
/// <summary> /// Return user object from a valid token. This method only checks the local Token Cache. /// </summary> /// <param name="request"></param> /// <returns>User object</returns> /// <exception cref="TokenDoesNotExistException"></exception> public async Task <User> GetUserFromValidToken(HttpRequest request) { var authorization = request.Headers[HeaderNames.Authorization]; string token = null; if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue)) { var scheme = headerValue.Scheme; token = headerValue.Parameter; } TokenCache cachedToken = CheckForValidTokenByToken(token); bool tokenValid = cachedToken != null; if (tokenValid) { return(cachedToken.User); } else { throw new TokenDoesNotExistException(); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { Request.Headers.TryGetValue("Authorization", out var authHeader); AuthenticationHeaderValue.TryParse(authHeader, out var authHeaderValue); if (string.IsNullOrEmpty(authHeaderValue?.Parameter)) { return(AuthenticateResult.Fail("Authorization header not provided")); } byte[] data = Convert.FromBase64String(authHeaderValue?.Parameter); string credentials = Encoding.UTF8.GetString(data); var split = credentials.Split(':', 2); if (split.Count() != 2) { return(AuthenticateResult.Fail("Invalid Authorization Header")); } var clientId = split[0]; var clientSecret = split[1]; if (clientId != "noxton" || clientSecret != "XcYcnx-=wb9;WP*V") { return(AuthenticateResult.Fail("Invalid Authorization Header")); } var claims = new[] { new Claim(ClaimTypes.NameIdentifier, "tesst") }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
public async Task <IActionResult> logout() { try { var authorization = Request.Headers[HeaderNames.Authorization]; if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue)) { var jwt = headerValue.Parameter; await _userservice.logout(jwt); } return(Ok()); } catch (Exception e) { if (e.Message.Length > 0) { return(BadRequest(e.Message)); } else { throw; } } }
protected override Task <AuthenticateResult> HandleAuthenticateAsync() { // Get Authorization header value if (!AuthenticationHeaderValue.TryParse(Request.Headers[AuthorizationHeaderName], out AuthenticationHeaderValue headerValue)) { //Invalid Authorization header return(Task.FromResult(AuthenticateResult.Fail("Cannot read authorization header."))); } var header = headerValue.Scheme; var valueh = headerValue.Parameter; if (!BasicSchemeName.Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { //Not Basic authentication header return(Task.FromResult(AuthenticateResult.Fail("Cannot read authorization sehema."))); } var identities = new List <ClaimsIdentity> { new ClaimsIdentity("custom auth type") }; var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme); return(Task.FromResult(AuthenticateResult.Success(ticket))); }
public string GetAgeToken() { string token = HttpContext.Request.Headers["Authorization"]; if (AuthenticationHeaderValue.TryParse(token, out var headerValue)) { // we have a valid AuthenticationHeaderValue that has the following details: var scheme = headerValue.Scheme; var parameter = headerValue.Parameter; // scheme will be "Bearer" // parmameter will be the token itself. var stream = parameter; var handler = new JwtSecurityTokenHandler(); var jsonToken = handler.ReadToken(stream); var tokenS = jsonToken as JwtSecurityToken; var jti = tokenS.Claims.First(claim => claim.Type == "Age").Value; string word = "The Age is : "; var result = word + jti; return(result); } return("Error"); }
// Helpers private async Task <AuthGUID> GetGUIDAsync(HttpRequest req) { AuthGUID authGUID = new AuthGUID(); AuthResultModel authResult = new AuthResultModel(false, AuthStatusCode.Unauthorized); // Get AuthentificationHeader from request AuthenticationHeaderValue.TryParse(req.Headers[HeaderNames.Authorization], out var authHeader); if (authHeader == null) { return new AuthGUID { AuthResult = authResult } } ; // Token validation with Auth0 servers ClaimsPrincipal claims = await Auth0.ValidateTokenAsync(authHeader); if (claims == null) { return new AuthGUID { AuthResult = authResult } } ; // Get Token Guid for Authorization string tokenGuid = claims.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value; authGUID.Acces = true; authGUID.GUID = tokenGuid; authGUID.AuthResult = new AuthResultModel(true, AuthStatusCode.Ok); return(authGUID); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out AuthenticationHeaderValue authHeader)) { try { if (string.IsNullOrEmpty(authHeader?.Parameter) || !authHeader.Scheme.Equals("Bearer", StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.Fail("Invalid Authorization Header")); } var jwtTokenString = authHeader.Parameter; var token = _tokenService.Read(jwtTokenString); var account = await _accountService.GetByUsernameAsync(GetEmailFromClaims(token.Claims)); if (account == null) { return(AuthenticateResult.Fail("User not found")); } var principal = _tokenService.Validate(jwtTokenString); if (principal == null) { return(AuthenticateResult.Fail("Token validation failed")); } return(AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name))); } catch (Exception ex) { return(AuthenticateResult.Fail(ex.Message)); } } return(AuthenticateResult.Fail("Missing Authorization Header")); }
public static async Task <IActionResult> CreateExperience( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "experience")] HttpRequest req, [Table("aramizexperience", Connection = "AzureWebJobsStorage")] IAsyncCollector <ExperienceEntity> exeperinceTable, ILogger log) { log.LogInformation("Creating new aramiz experience entity"); ClaimsPrincipal principal; AuthenticationHeaderValue.TryParse(req.Headers[HeaderNames.Authorization], out var authHeader); if ((principal = await Security.ValidateTokenAsync(authHeader)) == null) { return(new UnauthorizedResult()); } string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var input = JsonConvert.DeserializeObject <ExperienceCreateModel>(requestBody); var experienceEntity = new ExperienceModel { expEmployeeTitle = input.expEmployeeTitle, expCompanyLogoUri = input.expCompanyLogoUri, expCompany = input.expCompany, expLocation = input.expLocation, expCurrentWorkRole = input.expCurrentWorkRole, expStartDate = input.expStartDate, expEndDate = input.expEndDate, expWorkSubject = input.expWorkSubject, expWorkDescription = input.expWorkDescription, expWorkLinks = input.expWorkLinks }; await exeperinceTable.AddAsync(experienceEntity.ExperienceTableEntity()); return(new OkObjectResult(experienceEntity)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { // get header if (!AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out var authorization) || authorization.Scheme != Scheme.Name) { _results.Labels("none").Inc(); return(AuthenticateResult.NoResult()); } OneOf <AuthTokenPayload, TokenValidationError> result; using (_time.Measure()) result = await _auth.ValidateTokenAsync(authorization.Parameter); if (!result.TryPickT0(out var payload, out var error)) { _results.Labels("fail").Inc(); return(AuthenticateResult.Fail(error.ToString())); } // pass payload down the pipeline Context.Items[PayloadItemKey] = payload; // we don't use asp.net claims, but integrations like Sentry do var ticket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, payload.UserId) }, SchemeName)), SchemeName); _results.Labels("success").Inc(); return(AuthenticateResult.Success(ticket)); } catch (Exception e) { return(AuthenticateResult.Fail($"Authentication failed. {e.Message}")); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { string protectedToken = null; if (Request.Headers.TryGetValue("Authorization", out StringValues authHeader) && AuthenticationHeaderValue.TryParse(authHeader.ToString(), out AuthenticationHeaderValue auth) && !string.IsNullOrEmpty(auth.Parameter) && auth.Parameter.Length < 1000) { switch (auth.Scheme.ToLowerInvariant()) { case "basic": protectedToken = ParseBasicAuth(auth.Parameter); break; case "bearer": protectedToken = auth.Parameter; break; } } if (string.IsNullOrEmpty(protectedToken) && Request.Query.TryGetValue("token", out StringValues tokenQuery)) { protectedToken = tokenQuery.ToString(); } if (string.IsNullOrEmpty(protectedToken)) { Logger.LogInformation("No token found in 'Authorization: Bearer <token>', 'Authorization: Basic <base64(ignored:<token>)>', or '?token=<token>'"); return(AuthenticateResult.NoResult()); } if (!TryDecodeToken(protectedToken, out GitHubTokenData token)) { string reportToken = protectedToken; if (reportToken.Length > 10) { reportToken = reportToken.Substring(0, 5) + "..." + reportToken.Substring(reportToken.Length - 5); } Logger.LogWarning("Token failed to decode correctly, token signature... {token}", reportToken); return(AuthenticateResult.Fail("Invalid token")); } if (await _revocation.IsTokenRevokedAsync(token.UserId, token.TokenId)) { Logger.LogWarning("Revoked token used, user {user}, token {token}", token.UserId, token.TokenId); return(AuthenticateResult.Fail("Invalid token")); } (IEnumerable <Claim> userClaims, IEnumerable <Claim> groupClaims) = await Task.WhenAll( _resolver.GetUserInformationClaims(token.AccessToken, Context.RequestAborted), _resolver.GetMembershipClaims(token.AccessToken, Context.RequestAborted) ); var identity = new ClaimsIdentity(userClaims.Concat(groupClaims), Scheme.Name); var principal = new ClaimsPrincipal(new[] { identity }); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { string authHeaderValue = Request.Headers.TryGetAndReturn("Authorization").FirstOrDefault(); AuthenticationHeaderValue authHeader = null; if (!String.IsNullOrEmpty(authHeaderValue) && !AuthenticationHeaderValue.TryParse(authHeaderValue, out authHeader)) { return(AuthenticateResult.Fail("Unable to parse header")); } string scheme = authHeader?.Scheme.ToLower(); string token = null; if (authHeader != null && (scheme == BearerScheme || scheme == TokenScheme)) { token = authHeader.Parameter; } else if (authHeader != null && scheme == BasicScheme) { var authInfo = Request.GetBasicAuth(); if (authInfo != null) { if (authInfo.Username.ToLower() == "client") { token = authInfo.Password; } else if (authInfo.Password.ToLower() == "x-oauth-basic" || String.IsNullOrEmpty(authInfo.Password)) { token = authInfo.Username; } else { User user; try { user = await _userRepository.GetByEmailAddressAsync(authInfo.Username); } catch (Exception ex) { return(AuthenticateResult.Fail(ex)); } if (user == null || !user.IsActive) { return(AuthenticateResult.Fail("User is not valid")); } if (String.IsNullOrEmpty(user.Salt)) { return(AuthenticateResult.Fail("User is not valid")); } string encodedPassword = authInfo.Password.ToSaltedHash(user.Salt); if (!String.Equals(encodedPassword, user.Password)) { return(AuthenticateResult.Fail("User is not valid")); } return(AuthenticateResult.Success(CreateUserAuthenticationTicket(user))); } } } else { token = Request.GetQueryString("access_token"); if (String.IsNullOrEmpty(token)) { token = Request.GetQueryString("api_key"); } if (String.IsNullOrEmpty(token)) { token = Request.GetQueryString("apikey"); } } if (String.IsNullOrEmpty(token)) { return(AuthenticateResult.NoResult()); } var tokenRecord = await _tokenRepository.GetByIdAsync(token, o => o.Cache()); if (tokenRecord == null) { using (Logger.BeginScope(new ExceptionlessState().Property("Headers", Request.Headers))) Logger.LogWarning("Token {Token} for {Path} not found.", token, Request.Path); return(AuthenticateResult.Fail("Token is not valid")); } if (tokenRecord.ExpiresUtc.HasValue && tokenRecord.ExpiresUtc.Value < Foundatio.Utility.SystemClock.UtcNow) { using (Logger.BeginScope(new ExceptionlessState().Property("Headers", Request.Headers))) Logger.LogWarning("Token {Token} for {Path} expired on {TokenExpiresUtc}.", token, Request.Path, tokenRecord.ExpiresUtc.Value); return(AuthenticateResult.Fail("Token is not valid")); } if (!String.IsNullOrEmpty(tokenRecord.UserId)) { var user = await _userRepository.GetByIdAsync(tokenRecord.UserId, o => o.Cache()); if (user == null) { using (Logger.BeginScope(new ExceptionlessState().Property("Headers", Request.Headers))) Logger.LogWarning("Could not find user for token {Token} with user {user} for {Path}.", token, tokenRecord.UserId, Request.Path); return(AuthenticateResult.Fail("Token is not valid")); } return(AuthenticateResult.Success(CreateUserAuthenticationTicket(user, tokenRecord))); } return(AuthenticateResult.Success(CreateTokenAuthenticationTicket(tokenRecord))); }
public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var description = (ControllerActionDescriptor)context.ActionDescriptor; //匿名标识 var allowAnonymous = description.MethodInfo.GetCustomAttribute(typeof(AllowAnonymousAttribute)); if (allowAnonymous != null) { return; } var request = context.HttpContext.Request; string method = request.Method; string rawUrl = request.Path.Value + request.QueryString.Value; string date = request.Headers["Date"]; string content = null; if (request.Body.CanSeek) { request.Body.Position = 0; content = await new StreamReader(request.Body).ReadToEndAsync(); request.Body.Position = 0; } if (AuthenticationHeaderValue.TryParse(request.Headers["Authorization"], out AuthenticationHeaderValue authorization)) { if (String.Equals("PKC", authorization.Scheme, StringComparison.CurrentCultureIgnoreCase)) { string[] split = authorization.Parameter.Split(':'); string parkID = split[0]; string sign = split[1]; var parkPO = await new ParkRep <parkPO>().SingleOrDefaultAsync(parkID); if (parkPO != null) { string preString = method + "\n" + rawUrl + "\n" + date + "\n" + content + "\n"; string sha1 = Crypto.GetHMACSHA1(preString, parkPO.park_key); if (String.Equals(sign, sha1, StringComparison.CurrentCultureIgnoreCase)) { context.HttpContext.Items.Add("ParkUser", parkPO); return; } else { Log.Warn($"{parkID}签名计算不通过"); } } else { Log.Warn($"{parkID}应用不存在"); } } else { Log.Warn($"Authorization头格式不合法:{request.Headers["Authorization"]}"); } } else { Log.Warn($"Authorization头格式不合法:{request.Headers["Authorization"]}"); } context.Result = new UnauthorizedResult(); }
public void Configure( IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime, Func <DateTimeOffset> getDateTimeOffset, FileStoreForProcessStore processStoreForFileStore) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } var configuration = app.ApplicationServices.GetService <IConfiguration>(); var adminPassword = configuration.GetValue <string>(Configuration.AdminPasswordSettingKey); object avoidConcurrencyLock = new(); var processStoreFileStore = processStoreForFileStore.fileStore; PublicHostConfiguration?publicAppHost = null; void stopPublicApp() { lock (avoidConcurrencyLock) { if (publicAppHost != null) { logger.LogInformation("Begin to stop the public app."); publicAppHost?.webHost?.StopAsync(TimeSpan.FromSeconds(10)).Wait(); publicAppHost?.webHost?.Dispose(); publicAppHost?.processLiveRepresentation?.Dispose(); publicAppHost = null; } } } appLifetime.ApplicationStopping.Register(() => { stopPublicApp(); }); var processStoreWriter = new ProcessStoreWriterInFileStore( processStoreFileStore, getTimeForCompositionLogBatch: getDateTimeOffset, processStoreFileStore); void startPublicApp() { lock (avoidConcurrencyLock) { stopPublicApp(); logger.LogInformation("Begin to build the process live representation."); var restoreProcessResult = PersistentProcess.PersistentProcessLiveRepresentation.LoadFromStoreAndRestoreProcess( new ProcessStoreReaderInFileStore(processStoreFileStore), logger: logEntry => logger.LogInformation(logEntry)); var processLiveRepresentation = restoreProcessResult.process; logger.LogInformation("Completed building the process live representation."); var cyclicReductionStoreLock = new object(); DateTimeOffset?cyclicReductionStoreLastTime = null; var cyclicReductionStoreDistanceSeconds = (int)TimeSpan.FromMinutes(10).TotalSeconds; void maintainStoreReductions() { var currentDateTime = getDateTimeOffset(); System.Threading.Thread.MemoryBarrier(); var cyclicReductionStoreLastAge = currentDateTime - cyclicReductionStoreLastTime; if (!(cyclicReductionStoreLastAge?.TotalSeconds < cyclicReductionStoreDistanceSeconds)) { if (System.Threading.Monitor.TryEnter(cyclicReductionStoreLock)) { try { var afterLockCyclicReductionStoreLastAge = currentDateTime - cyclicReductionStoreLastTime; if (afterLockCyclicReductionStoreLastAge?.TotalSeconds < cyclicReductionStoreDistanceSeconds) { return; } lock (avoidConcurrencyLock) { var(reductionRecord, _) = processLiveRepresentation.StoreReductionRecordForCurrentState(processStoreWriter !); } cyclicReductionStoreLastTime = currentDateTime; System.Threading.Thread.MemoryBarrier(); } finally { System.Threading.Monitor.Exit(cyclicReductionStoreLock); } } } } IWebHost buildWebHost( PersistentProcess.ProcessAppConfig processAppConfig, IReadOnlyList <string> publicWebHostUrls) { var appConfigTree = Composition.ParseAsTreeWithStringPath(processAppConfig.appConfigComponent).Ok !; var appConfigFilesNamesAndContents = appConfigTree.EnumerateBlobsTransitive(); var webAppConfigurationFile = appConfigFilesNamesAndContents .FirstOrDefault(filePathAndContent => filePathAndContent.path.SequenceEqual(JsonFilePath)) .blobContent; var webAppConfiguration = webAppConfigurationFile == null ? null : System.Text.Json.JsonSerializer.Deserialize <WebAppConfigurationJsonStructure>(Encoding.UTF8.GetString(webAppConfigurationFile.ToArray())); return (Microsoft.AspNetCore.WebHost.CreateDefaultBuilder() .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }) .ConfigureKestrel(kestrelOptions => { kestrelOptions.ConfigureHttpsDefaults(httpsOptions => { httpsOptions.ServerCertificateSelector = (c, s) => FluffySpoon.AspNet.LetsEncrypt.LetsEncryptRenewalService.Certificate; }); }) .UseUrls(publicWebHostUrls.ToArray()) .UseStartup <StartupPublicApp>() .WithSettingDateTimeOffsetDelegate(getDateTimeOffset) .ConfigureServices(services => { services.AddSingleton( new WebAppAndElmAppConfig( WebAppConfiguration: webAppConfiguration, ProcessEventInElmApp: serializedEvent => { lock (avoidConcurrencyLock) { var elmEventResponse = processLiveRepresentation.ProcessElmAppEvent( processStoreWriter !, serializedEvent); maintainStoreReductions(); return elmEventResponse; } }, SourceComposition: processAppConfig.appConfigComponent, InitOrMigrateCmds: restoreProcessResult.initOrMigrateCmds )); }) .Build()); } if (processLiveRepresentation?.lastAppConfig != null) { var publicWebHostUrls = configuration.GetSettingPublicWebHostUrls(); var webHost = buildWebHost( processLiveRepresentation.lastAppConfig, publicWebHostUrls: publicWebHostUrls); webHost.StartAsync(appLifetime.ApplicationStopping).Wait(); logger.LogInformation("Started the public app at '" + string.Join(",", publicWebHostUrls) + "'."); publicAppHost = new PublicHostConfiguration( processLiveRepresentation: processLiveRepresentation, webHost: webHost); } } } startPublicApp(); app.Run(async(context) => { var syncIOFeature = context.Features.Get <Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature>(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; } { context.Request.Headers.TryGetValue("Authorization", out var requestAuthorizationHeaderValue); context.Response.Headers.Add("X-Powered-By", "Elm Fullstack " + elm_fullstack.Program.AppVersionId); AuthenticationHeaderValue.TryParse( requestAuthorizationHeaderValue.FirstOrDefault(), out var requestAuthorization); if (!(0 < adminPassword?.Length)) { context.Response.StatusCode = 403; await context.Response.WriteAsync("The admin interface is not available because the admin password is not yet configured."); return; } var buffer = new byte[400]; var decodedRequestAuthorizationParameter = Convert.TryFromBase64String(requestAuthorization?.Parameter ?? "", buffer, out var bytesWritten) ? Encoding.UTF8.GetString(buffer, 0, bytesWritten) : null; var requestAuthorizationPassword = decodedRequestAuthorizationParameter?.Split(':')?.ElementAtOrDefault(1); if (!(string.Equals(adminPassword, requestAuthorizationPassword) && string.Equals("basic", requestAuthorization?.Scheme, StringComparison.OrdinalIgnoreCase))) { context.Response.StatusCode = 401; context.Response.Headers.Add( "WWW-Authenticate", @"Basic realm=""" + context.Request.Host + @""", charset=""UTF-8"""); await context.Response.WriteAsync("Unauthorized"); return; } } async System.Threading.Tasks.Task deployElmApp(bool initElmAppState) { var memoryStream = new MemoryStream(); context.Request.Body.CopyTo(memoryStream); var webAppConfigZipArchive = memoryStream.ToArray(); { try { var filesFromZipArchive = ZipArchive.EntriesFromZipArchive(webAppConfigZipArchive).ToImmutableList(); if (filesFromZipArchive.Count < 1) { throw new Exception("Contains no files."); } } catch (Exception e) { context.Response.StatusCode = 400; await context.Response.WriteAsync("Malformed web app config zip-archive:\n" + e); return; } } var appConfigTree = Composition.SortedTreeFromSetOfBlobsWithCommonFilePath( ZipArchive.EntriesFromZipArchive(webAppConfigZipArchive)); var appConfigComponent = Composition.FromTreeWithStringPath(appConfigTree); var appConfigHashBase16 = CommonConversion.StringBase16FromByteArray(Composition.GetHash(appConfigComponent)); logger.LogInformation("Got request to deploy app config " + appConfigHashBase16); processStoreWriter.StoreComponent(appConfigComponent); var appConfigValueInFile = new ValueInFileStructure { HashBase16 = appConfigHashBase16 }; var compositionLogEvent = CompositionLogRecordInFile.CompositionEvent.EventForDeployAppConfig( appConfigValueInFile: appConfigValueInFile, initElmAppState: initElmAppState); await attemptContinueWithCompositionEventAndSendHttpResponse(compositionLogEvent); } var apiRoutes = new[] { new ApiRoute ( path: PathApiGetDeployedAppConfig, methods: ImmutableDictionary <string, Func <HttpContext, PublicHostConfiguration?, System.Threading.Tasks.Task> > .Empty .Add("get", async(context, publicAppHost) => { var appConfig = publicAppHost?.processLiveRepresentation?.lastAppConfig.appConfigComponent; if (appConfig == null) { context.Response.StatusCode = 404; await context.Response.WriteAsync("I did not find an app config in the history. Looks like no app was deployed so far."); return; } var appConfigHashBase16 = CommonConversion.StringBase16FromByteArray(Composition.GetHash(appConfig)); var appConfigTree = Composition.ParseAsTreeWithStringPath(appConfig).Ok; if (appConfigTree == null) { throw new Exception("Failed to parse as tree with string path"); } var appConfigZipArchive = ZipArchive.ZipArchiveFromEntries( Composition.TreeToFlatDictionaryWithPathComparer(appConfigTree)); context.Response.StatusCode = 200; context.Response.Headers.ContentLength = appConfigZipArchive.LongLength; context.Response.Headers.Add("Content-Disposition", new ContentDispositionHeaderValue("attachment") { FileName = appConfigHashBase16 + ".zip" }.ToString()); context.Response.Headers.Add("Content-Type", new MediaTypeHeaderValue("application/zip").ToString()); await context.Response.Body.WriteAsync(appConfigZipArchive); }) ), new ApiRoute ( path: PathApiElmAppState, methods: ImmutableDictionary <string, Func <HttpContext, PublicHostConfiguration?, System.Threading.Tasks.Task> > .Empty .Add("get", async(context, publicAppHost) => { if (publicAppHost == null) { context.Response.StatusCode = 400; await context.Response.WriteAsync("Not possible because there is no app (state)."); return; } var processLiveRepresentation = publicAppHost?.processLiveRepresentation; var components = new List <Composition.Component>(); var storeWriter = new DelegatingProcessStoreWriter ( StoreComponentDelegate: components.Add, StoreProvisionalReductionDelegate: _ => { }, AppendCompositionLogRecordDelegate: _ => throw new Exception("Unexpected use of interface.") ); var reductionRecord = processLiveRepresentation?.StoreReductionRecordForCurrentState(storeWriter).reductionRecord; if (reductionRecord == null) { context.Response.StatusCode = 500; await context.Response.WriteAsync("Not possible because there is no Elm app deployed at the moment."); return; } var elmAppStateReductionHashBase16 = reductionRecord.elmAppState?.HashBase16; var elmAppStateReductionComponent = components.First(c => CommonConversion.StringBase16FromByteArray(Composition.GetHash(c)) == elmAppStateReductionHashBase16); if (elmAppStateReductionComponent.BlobContent == null) { throw new Exception("elmAppStateReductionComponent is not a blob"); } var elmAppStateReductionString = Encoding.UTF8.GetString(elmAppStateReductionComponent.BlobContent); context.Response.StatusCode = 200; context.Response.ContentType = "application/json"; await context.Response.WriteAsync(elmAppStateReductionString); }) .Add("post", async(context, publicAppHost) => { if (publicAppHost == null) { context.Response.StatusCode = 400; await context.Response.WriteAsync("Not possible because there is no app (state)."); return; } var elmAppStateToSet = new StreamReader(context.Request.Body, Encoding.UTF8).ReadToEndAsync().Result; var elmAppStateComponent = Composition.Component.Blob(Encoding.UTF8.GetBytes(elmAppStateToSet)); var appConfigValueInFile = new ValueInFileStructure { HashBase16 = CommonConversion.StringBase16FromByteArray(Composition.GetHash(elmAppStateComponent)) }; processStoreWriter.StoreComponent(elmAppStateComponent); await attemptContinueWithCompositionEventAndSendHttpResponse( new CompositionLogRecordInFile.CompositionEvent { SetElmAppState = appConfigValueInFile }); }) ), new ApiRoute ( path: PathApiDeployAndInitAppState, methods: ImmutableDictionary <string, Func <HttpContext, PublicHostConfiguration?, System.Threading.Tasks.Task> > .Empty .Add("post", async(context, publicAppHost) => await deployElmApp(initElmAppState: true)) ), new ApiRoute ( path: PathApiDeployAndMigrateAppState, methods: ImmutableDictionary <string, Func <HttpContext, PublicHostConfiguration?, System.Threading.Tasks.Task> > .Empty .Add("post", async(context, publicAppHost) => await deployElmApp(initElmAppState: false)) ), new ApiRoute ( path: PathApiReplaceProcessHistory, methods: ImmutableDictionary <string, Func <HttpContext, PublicHostConfiguration?, System.Threading.Tasks.Task> > .Empty .Add("post", async(context, publicAppHost) => { var memoryStream = new MemoryStream(); context.Request.Body.CopyTo(memoryStream); var webAppConfigZipArchive = memoryStream.ToArray(); var replacementFiles = ZipArchive.EntriesFromZipArchive(webAppConfigZipArchive) .Select(filePathAndContent => (path: filePathAndContent.name.Split(new[] { '/', '\\' }).ToImmutableList() , filePathAndContent.content)) .ToImmutableList(); lock (avoidConcurrencyLock) { stopPublicApp(); foreach (var filePath in processStoreFileStore.ListFilesInDirectory(ImmutableList <string> .Empty).ToImmutableList()) { processStoreFileStore.DeleteFile(filePath); } foreach (var replacementFile in replacementFiles) { processStoreFileStore.SetFileContent(replacementFile.path, replacementFile.content); } startPublicApp(); } context.Response.StatusCode = 200; await context.Response.WriteAsync("Successfully replaced the process history."); }) ), }; foreach (var apiRoute in apiRoutes) { if (!context.Request.Path.Equals(new PathString(apiRoute.path))) { continue; } var matchingMethod = apiRoute.methods .FirstOrDefault(m => m.Key.ToUpperInvariant() == context.Request.Method.ToUpperInvariant()); if (matchingMethod.Value == null) { var supportedMethodsNames = apiRoute.methods.Keys.Select(m => m.ToUpperInvariant()).ToList(); var guide = HtmlFromLines( "<h2>Method Not Allowed</h2>", "", context.Request.Path.ToString() + " is a valid path, but the method " + context.Request.Method.ToUpperInvariant() + " is not supported here.", "Only following " + (supportedMethodsNames.Count == 1 ? "method is" : "methods are") + " supported here: " + string.Join(", ", supportedMethodsNames), "", "", ApiGuide); context.Response.StatusCode = 405; await context.Response.WriteAsync(HtmlDocument(guide)); return; } matchingMethod.Value?.Invoke(context, publicAppHost); return; } if (context.Request.Path.StartsWithSegments(new PathString(PathApiRevertProcessTo), out var revertToRemainingPath)) { if (!string.Equals(context.Request.Method, "post", StringComparison.InvariantCultureIgnoreCase)) { context.Response.StatusCode = 405; await context.Response.WriteAsync("Method not supported."); return; } var processVersionId = revertToRemainingPath.ToString().Trim('/'); var processVersionCompositionRecord = new ProcessStoreReaderInFileStore(processStoreFileStore) .EnumerateSerializedCompositionLogRecordsReverse() .FirstOrDefault(compositionEntry => CompositionLogRecordInFile.HashBase16FromCompositionRecord(compositionEntry) == processVersionId); if (processVersionCompositionRecord == null) { context.Response.StatusCode = 404; await context.Response.WriteAsync("Did not find process version '" + processVersionId + "'."); return; } await attemptContinueWithCompositionEventAndSendHttpResponse(new CompositionLogRecordInFile.CompositionEvent { RevertProcessTo = new ValueInFileStructure { HashBase16 = processVersionId }, }); return; } TruncateProcessHistoryReport truncateProcessHistory(TimeSpan productionBlockDurationLimit) { var beginTime = CommonConversion.TimeStringViewForReport(DateTimeOffset.UtcNow); var totalStopwatch = System.Diagnostics.Stopwatch.StartNew(); var numbersOfThreadsToDeleteFiles = 4; var filePathsInProcessStorePartitions = processStoreFileStore.ListFiles() .Select((s, i) => (s, i)) .GroupBy(x => x.i % numbersOfThreadsToDeleteFiles) .Select(g => g.Select(x => x.s).ToImmutableList()) .ToImmutableList(); lock (avoidConcurrencyLock) { var lockStopwatch = System.Diagnostics.Stopwatch.StartNew(); var storeReductionStopwatch = System.Diagnostics.Stopwatch.StartNew(); var storeReductionReport = publicAppHost?.processLiveRepresentation?.StoreReductionRecordForCurrentState(processStoreWriter).report; storeReductionStopwatch.Stop(); var getFilesForRestoreStopwatch = System.Diagnostics.Stopwatch.StartNew(); var filesForRestore = PersistentProcess.PersistentProcessLiveRepresentation.GetFilesForRestoreProcess( processStoreFileStore).files .Select(filePathAndContent => filePathAndContent.Key) .ToImmutableHashSet(EnumerableExtension.EqualityComparer <IImmutableList <string> >()); getFilesForRestoreStopwatch.Stop(); var deleteFilesStopwatch = System.Diagnostics.Stopwatch.StartNew(); var totalDeletedFilesCount = filePathsInProcessStorePartitions .AsParallel() .WithDegreeOfParallelism(numbersOfThreadsToDeleteFiles) .Select(partitionFilePaths => { int partitionDeletedFilesCount = 0; foreach (var filePath in partitionFilePaths) { if (filesForRestore.Contains(filePath)) { continue; } if (productionBlockDurationLimit < lockStopwatch.Elapsed) { break; } processStoreFileStore.DeleteFile(filePath); ++partitionDeletedFilesCount; } return(partitionDeletedFilesCount); }) .Sum(); deleteFilesStopwatch.Stop(); return(new TruncateProcessHistoryReport ( beginTime: beginTime, filesForRestoreCount: filesForRestore.Count, discoveredFilesCount: filePathsInProcessStorePartitions.Sum(partition => partition.Count), deletedFilesCount: totalDeletedFilesCount, storeReductionTimeSpentMilli: (int)storeReductionStopwatch.ElapsedMilliseconds, storeReductionReport: storeReductionReport, getFilesForRestoreTimeSpentMilli: (int)getFilesForRestoreStopwatch.ElapsedMilliseconds, deleteFilesTimeSpentMilli: (int)deleteFilesStopwatch.ElapsedMilliseconds, lockedTimeSpentMilli: (int)lockStopwatch.ElapsedMilliseconds, totalTimeSpentMilli: (int)totalStopwatch.ElapsedMilliseconds )); } } if (context.Request.Path.Equals(new PathString(PathApiTruncateProcessHistory))) { var truncateResult = truncateProcessHistory(productionBlockDurationLimit: TimeSpan.FromMinutes(1)); context.Response.StatusCode = 200; context.Response.ContentType = "application/json"; await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(truncateResult)); return; } { if (context.Request.Path.StartsWithSegments( new PathString(PathApiProcessHistoryFileStoreGetFileContent), out var remainingPathString)) { if (!string.Equals(context.Request.Method, "get", StringComparison.InvariantCultureIgnoreCase)) { context.Response.StatusCode = 405; await context.Response.WriteAsync("Method not supported."); return; } var filePathInStore = remainingPathString.ToString().Trim('/').Split('/').ToImmutableList(); var fileContent = processStoreFileStore.GetFileContent(filePathInStore); if (fileContent == null) { context.Response.StatusCode = 404; await context.Response.WriteAsync("No file at '" + string.Join("/", filePathInStore) + "'."); return; } context.Response.StatusCode = 200; context.Response.ContentType = "application/octet-stream"; await context.Response.Body.WriteAsync(fileContent as byte[] ?? fileContent.ToArray()); return; } } { if (context.Request.Path.StartsWithSegments( new PathString(PathApiProcessHistoryFileStoreListFilesInDirectory), out var remainingPathString)) { if (!string.Equals(context.Request.Method, "get", StringComparison.InvariantCultureIgnoreCase)) { context.Response.StatusCode = 405; await context.Response.WriteAsync("Method not supported."); return; } var filePathInStore = remainingPathString.ToString().Trim('/').Split('/').ToImmutableList(); var filesPaths = processStoreFileStore.ListFilesInDirectory(filePathInStore); var filesPathsList = string.Join('\n', filesPaths.Select(path => string.Join('/', path))); context.Response.StatusCode = 200; context.Response.ContentType = "application/octet-stream"; await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(filesPathsList)); return; } } (int statusCode, AttemptContinueWithCompositionEventReport responseReport)attemptContinueWithCompositionEvent( CompositionLogRecordInFile.CompositionEvent compositionLogEvent) { lock (avoidConcurrencyLock) { var storeReductionStopwatch = System.Diagnostics.Stopwatch.StartNew(); var storeReductionReport = publicAppHost?.processLiveRepresentation?.StoreReductionRecordForCurrentState(processStoreWriter).report; storeReductionStopwatch.Stop(); var(statusCode, report) = AttemptContinueWithCompositionEventAndCommit( compositionLogEvent, processStoreFileStore, testContinueLogger: logEntry => logger.LogInformation(logEntry)); report = report with { storeReductionTimeSpentMilli = (int)storeReductionStopwatch.ElapsedMilliseconds, storeReductionReport = storeReductionReport }; startPublicApp(); return(statusCode, report); } } async System.Threading.Tasks.Task attemptContinueWithCompositionEventAndSendHttpResponse( CompositionLogRecordInFile.CompositionEvent compositionLogEvent, ILogger? logger = null) { logger?.LogInformation( "Begin attempt to continue with composition event: " + System.Text.Json.JsonSerializer.Serialize(compositionLogEvent)); var(statusCode, attemptReport) = attemptContinueWithCompositionEvent(compositionLogEvent); var responseBodyString = System.Text.Json.JsonSerializer.Serialize(attemptReport); context.Response.StatusCode = statusCode; await context.Response.WriteAsync(responseBodyString); } if (context.Request.Path.Equals(PathString.Empty) || context.Request.Path.Equals(new PathString("/"))) { var httpApiGuide = HtmlFromLines( "<h3>HTTP APIs</h3>\n" + HtmlFromLines(apiRoutes.Select(HtmlToDescribeApiRoute).ToArray()) ); context.Response.StatusCode = 200; await context.Response.WriteAsync( HtmlDocument( HtmlFromLines( "Welcome to the Elm Fullstack admin interface version " + elm_fullstack.Program.AppVersionId + ".", httpApiGuide, "", ApiGuide))); return; } context.Response.StatusCode = 404; await context.Response.WriteAsync("Not Found"); return; }); }
protected override Task <AuthenticateResult> HandleAuthenticateAsync() { //We are expecting a header such as Authorization: <Schema> <key> //If this is not present, we will return NoResult and move on to the next authentication handler. if (!Request.Headers.TryGetValue(HeaderNames.Authorization, out StringValues values) || !values.Any()) { return(Task.FromResult(AuthenticateResult.NoResult())); } if (!AuthenticationHeaderValue.TryParse(values.First(), out AuthenticationHeaderValue authHeader)) { return(Task.FromResult(AuthenticateResult.Fail("Invalid authentication header"))); } if (!string.Equals(authHeader.Scheme, Scheme.Name, StringComparison.OrdinalIgnoreCase)) { return(Task.FromResult(AuthenticateResult.NoResult())); } //The user is passing a base 64-encoded version of the secret //We will be hash this and compare it to the secret in our configuration. byte[] secret = new byte[32]; Span <byte> span = new Span <byte>(secret); if (!Convert.TryFromBase64String(authHeader.Parameter, span, out int bytesWritten) || bytesWritten < 32) { return(Task.FromResult(AuthenticateResult.Fail("Invalid Api Key format"))); } //HACK IOptionsMonitor and similiar do not properly update here even though the underlying //configuration is updated. We get the value directly from IConfiguration. var authenticationOptions = new ApiAuthenticationOptions(); IConfiguration configService = Context.RequestServices.GetRequiredService <IConfiguration>(); configService.Bind(ApiAuthenticationOptions.ConfigurationKey, authenticationOptions); string apiKeyHash = authenticationOptions.ApiKeyHash; if (apiKeyHash == null) { return(Task.FromResult(AuthenticateResult.Fail("Server does not contain Api Key"))); } if (string.IsNullOrEmpty(authenticationOptions.ApiKeyHashType)) { return(Task.FromResult(AuthenticateResult.Fail("Missing hash algorithm"))); } if (DisallowedHashAlgorithms.Contains(authenticationOptions.ApiKeyHashType, StringComparer.OrdinalIgnoreCase)) { return(Task.FromResult(AuthenticateResult.Fail($"Disallowed hash algorithm {authenticationOptions.ApiKeyHashType}"))); } using HashAlgorithm algorithm = HashAlgorithm.Create(authenticationOptions.ApiKeyHashType); if (algorithm == null) { return(Task.FromResult(AuthenticateResult.Fail($"Invalid hash algorithm {authenticationOptions.ApiKeyHashType}"))); } byte[] hashedSecret = algorithm.ComputeHash(secret); //ApiKeyHash is represented as a hex string. e.g. AABBCCDDEEFF byte[] apiKeyHashBytes = new byte[apiKeyHash.Length / 2]; for (int i = 0; i < apiKeyHash.Length; i += 2) { if (!byte.TryParse(apiKeyHash.AsSpan(i, 2), NumberStyles.HexNumber, provider: NumberFormatInfo.InvariantInfo, result: out byte resultByte)) { return(Task.FromResult(AuthenticateResult.Fail("Invalid Api Key hash"))); } apiKeyHashBytes[i / 2] = resultByte; } if (hashedSecret.SequenceEqual(apiKeyHashBytes)) { return(Task.FromResult(AuthenticateResult.Success( new AuthenticationTicket( new ClaimsPrincipal(new[] { new ClaimsIdentity(AuthConstants.ApiKeySchema) }), AuthConstants.ApiKeySchema)))); } else { return(Task.FromResult(AuthenticateResult.Fail("Invalid Api Key"))); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { try { this.Logger.LogInformation("{LogKey:l} apikey handle", LogKeys.Authentication); if (this.Request.Host.Host.SafeEquals("localhost") && this.Options.IgnoreLocal) { // ignore for localhost var identity = new ClaimsIdentity( this.Options.Claims.Safe().Select(c => new Claim(c.Key, c.Value)) .Insert(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationKeys.ApiKeyScheme)) .Insert(new Claim(ClaimTypes.Name, ClaimsIdentity.DefaultIssuer)) .DistinctBy(c => c.Type), this.Scheme.Name); var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), this.Scheme.Name); this.Logger.LogInformation($"{{LogKey:l}} apikey authenticated (name={identity.Name})", LogKeys.Authentication); return(AuthenticateResult.Success(ticket)); } string value; if (this.Request.Query.TryGetValue("apikey", out var queryValue)) { // also allow the auth header to be sent in the querystring (for easy dashboard usage) value = queryValue.ToString(); } else { if (!this.Request.Headers.ContainsKey(AuthenticationKeys.AuthorizationHeaderName)) { return(AuthenticateResult.NoResult()); //Authorization header not in request } if (!AuthenticationHeaderValue.TryParse(this.Request.Headers[AuthenticationKeys.AuthorizationHeaderName], out var headerValue)) { return(AuthenticateResult.NoResult()); //Invalid Authorization header } else { value = headerValue.Parameter; } if (!AuthenticationKeys.ApiKeyScheme.Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.NoResult()); //Not a apikey authentication header } } if (value.IsNullOrEmpty()) { return(AuthenticateResult.NoResult()); //No apikey authentication value in header or query } //var context = new ApiKeyValidationContext(this.Context, this.Scheme, this.Options) { ApiKey = headerValue.Parameter }; //await this.Events.OnValidation(context); //if (context.Result != null) //{ // return context.Result; //} #pragma warning disable SA1008 // Opening parenthesis must be spaced correctly var(authenticated, claims) = this.service.Validate(value); #pragma warning restore SA1008 // Opening parenthesis must be spaced correctly if (authenticated) { var identity = new ClaimsIdentity( this.Options.Claims.Safe().Select(c => new Claim(c.Key, c.Value)).Concat(claims.Safe()) .Insert(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationKeys.ApiKeyScheme)).DistinctBy(c => c.Type), this.Scheme.Name); var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), this.Scheme.Name); this.Logger.LogInformation($"{{LogKey:l}} apikey authenticated (name={identity.Name})", LogKeys.Authentication); return(AuthenticateResult.Success(ticket)); } this.Logger.LogWarning("{LogKey:l} apikey not authenticated", LogKeys.Authentication); return(AuthenticateResult.Fail("not authenticated")); } catch (Exception ex) { this.Logger.LogError(ex, $"{{LogKey:l}} {ex.Message}", LogKeys.Authentication); var context = new ErrorContext(this.Context, this.Scheme, this.Options) { Exception = ex }; if (this.Events != null) { await this.Events.Error(context); if (context.Result != null) { return(context.Result); } } throw; } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { var now = _systemClock.UtcNow.UtcDateTime; if (!Request.Headers.ContainsKey("Authorization")) { Logger.LogError("Missing Authorization Header"); return(AuthenticateResult.Fail("Missing Authorization Header")); } ClaimsPrincipal principal = null; try { AuthenticationHeaderValue authenticationHeader; if (AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out authenticationHeader)) { if (authenticationHeader.Scheme == "Basic") { var credentialBytes = Convert.FromBase64String(authenticationHeader.Parameter); var credentialString = Encoding.UTF8.GetString(credentialBytes); if (credentialString.Contains(":")) { var credentials = credentialString.Split(new[] { ':' }, 2); var email = credentials[0]; var password = credentials[1]; var user = await _authenticationService.AuthenticateUserWithPassword(email, password); if (user == null) { //bad password Logger.LogError("Invalid Username or password"); return(AuthenticateResult.Fail("Invalid Username or Password")); } else { //make a token and put it in the response header? Logger.LogInformation("Authenticated User {@email} via email/password", user.Email); var jwt = await _authenticationService.IssueJwtToUser(user.Id); principal = _authenticationService.ValidateSignedJwtToken(jwt); Response.Headers.Add("Authorization", "Token " + jwt); } } } else if (authenticationHeader.Scheme == "Token" || authenticationHeader.Scheme == "Bearer") //TODO: remove "Token" { if ((new JwtSecurityTokenHandler()).CanReadToken(authenticationHeader.Parameter)) { var jwtPrincipal = _authenticationService.ValidateSignedJwtToken(authenticationHeader.Parameter); var parsed = jwtPrincipal.ParseAllClaims(); //TODO: update this so that only superseded/expired token are in the db, "good" tokens will not be var token = await _tokenRepository.GetToken(parsed.Token.TokenGuid); if (token == null || (token.ExpiredAt.HasValue && token.ExpiredAt < now)) { //note we do NOT set the principle, it's expired so we let it fail as invalid } else if ((parsed.Minimal.HasValue && parsed.Minimal.Value) || (token.SupersededAt.HasValue && token.SupersededAt < now)) { //token is valid, but needs to be updated due to some change that was made to data contained therein //OR the token is a minimal one which needs to be repalced with a "full" token var refreshedJwt = await _authenticationService.IssueJwtToUser(parsed.User.Id, token.TokenGuid); //send the updated token back to client Response.Headers.Add("Authorization", "Token " + refreshedJwt); principal = _authenticationService.ValidateSignedJwtToken(refreshedJwt); } else { principal = jwtPrincipal; } Logger.LogInformation("Authenticated User {@id} via bearer token {@tokenGuid}", parsed.User.Id, parsed.Token.TokenGuid); } } else { Logger.LogError("Invalid Authorization Header"); //it's not a token and it's not a basic, what is it? return(AuthenticateResult.Fail("Invalid Authorization Header")); } } else { Logger.LogError("Invalid Authorization Header"); //we can't understand the auth header return(AuthenticateResult.Fail("Invalid Authorization Header")); } } catch (Exception ex) { Logger.LogError("Exception in Authorization {@ex}", ex); //some exception we weren't ready for, likely a malformed header return(AuthenticateResult.Fail("Invalid Authorization Header")); } if (principal == null) { //this shouldn't actually happen, but just in case Logger.LogError("Invalid Username or Password"); return(AuthenticateResult.Fail("Invalid Username or Password")); } var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey(AuthorizationHeaderName)) { //Authorization header not in request return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers[AuthorizationHeaderName], out AuthenticationHeaderValue headerValue)) { //Invalid Authorization header return(AuthenticateResult.NoResult()); } if (!BasicSchemeName.Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { //Not Basic authentication header return(AuthenticateResult.NoResult()); } try { if (string.IsNullOrEmpty(headerValue.Parameter)) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidToken, "Invalid token"))); } byte[] headerValueBytes = Convert.FromBase64String(headerValue.Parameter); string userAndPassword = Encoding.UTF8.GetString(headerValueBytes); string[] parts = userAndPassword.Split(':'); if (parts.Length != 2) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidAutheHeader, "Invalid Basic authentication header"))); } string tenancyName = parts[0]; string apiKey = parts[1]; string userId = ""; string tenantId = ""; if (!string.IsNullOrEmpty(tenancyName)) { var tenants = await _tenantRepository.GetAll().IgnoreQueryFilters() .Where(o => o.ApiKey == apiKey && o.TenancyName == tenancyName && !o.IsDeleted && o.IsActive).ToListAsync(); if (tenants.Count == 0) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidInput, "Invalid tenancyname or apikey"))); } if (!tenants[0].IsActive) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_RefuseAuthorization, "tenant is banish"))); } var user = await this._userRepository.GetAll().IgnoreQueryFilters().SingleAsync(o => o.UserName == "admin" && o.TenantId == tenants[0].Id); tenantId = tenants[0].Id.ToString(); userId = user.Id.ToString(); } else if (apiKey.Equals(Options.SystemApiKey)) { var user = await this._userRepository.GetAll().IgnoreQueryFilters().SingleAsync(o => o.UserName == "admin" && o.TenantId == null); userId = user.Id.ToString(); } else { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidInput, "Invalid tenancyname or apikey"))); } var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId), new Claim(AbpClaimTypes.TenantId, tenantId), new Claim(AbpClaimTypes.UserName, StaticRoleNames.Host.Admin) }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) when(ex is FormatException || ex is DecoderFallbackException) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidToken, "Invalid token"))); } catch (Exception ex) { LogHelper.Logger.Error("basic auth", ex); return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.SytemError, "Invalid auth request"))); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Cookies.ContainsKey(AccessToken) || !Request.Cookies.ContainsKey(User_Id)) { Log.Error("No Access Token or User Id found."); return(await Task.FromResult(AuthenticateResult.NoResult())); } if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[AccessToken]}", out AuthenticationHeaderValue headerValue)) { Log.Error("Could not Parse Token from Authentication Header."); return(await Task.FromResult(AuthenticateResult.NoResult())); } if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[User_Id]}", out AuthenticationHeaderValue headerValueUid)) { Log.Error("Could not Parse User Id from Authentication Header."); return(await Task.FromResult(AuthenticateResult.NoResult())); } try { /* STEP 1. Get the Validation Parameters for our applications JWT Token */ var key = Encoding.ASCII.GetBytes(_appSettings.Secret); /* STEP 2. Create an instance of Jwt token handler */ var handler = new JwtSecurityTokenHandler(); /* STEP 3. Create an instance of Jwt token validation parameters */ TokenValidationParameters validationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, ValidateIssuer = true, ValidateAudience = true, ValidIssuer = _appSettings.Site, ValidAudience = _appSettings.Audience, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; /* STEP 4. Get the Data protection service instance */ var protectorProvider = _provider.GetService <IDataProtectionProvider>(); /* STEP 5. create a protector instance */ var protector = protectorProvider.CreateProtector(_dataProtectionKeys.ApplicationUserKey); /* STEP 6. Layer One Unprotect the user id */ var decryptedUid = protector.Unprotect(headerValueUid.Parameter); /* STEP 7. Layer One Unprotect the user token */ var decryptedToken = protector.Unprotect(headerValue.Parameter); /* STEP 8. Create an instance of the user tokenModel */ TokenEntities tokenModel = new TokenEntities(); /* STEP 9 Get the existing token for the user from Database using a scoped request */ using (var scope = _provider.CreateScope()) { var dbContextService = scope.ServiceProvider.GetService <ApplicationDbContext>(); var userToken = dbContextService.Tokens.Include(x => x.User) .FirstOrDefault(ut => ut.UserId == decryptedUid && ut.User.UserName == Request.Cookies[Username] && ut.User.Id == decryptedUid && ut.User.UserRole == "Administrator"); tokenModel = userToken; } /* Step 11. Check if tokenmodel is null */ if (tokenModel == null) { return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this Page"))); } /* STEP 12. Apply second layer of decryption using the key store in the token model */ /* STEP 12.1 Create Protector instance for layer two using token model key */ /* IMPORTANT - If no key exists or key is invalid - exception will be thrown */ IDataProtector layerTwoProtector = protectorProvider.CreateProtector(tokenModel?.EncryptionKeyJwt); string decryptedTokenLayerTwo = layerTwoProtector.Unprotect(decryptedToken); /* STEP 13. Validate the token we received - using validation parameters set in step 3 */ /* IMPORTANT - If the validation fails - the method ValidateToken will throw exception */ var validateToken = handler.ValidateToken(decryptedTokenLayerTwo, validationParameters, out var securityToken); /* STEP 14. Checking Token Signature */ if (!(securityToken is JwtSecurityToken jwtSecurityToken) || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized"))); } /* STEP 15. Extract the username from the validated token */ var username = validateToken.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value; if (Request.Cookies[Username] != username) { return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this Page"))); } /* STEP 16. Get User by their email */ var user = await _userManager.FindByNameAsync(username); /* STEP 17. If user does not exist return authentication failed result */ if (user == null) { return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this Page"))); } /* STEP 18. We need to check if the user belongs to the group of user-roles */ if (!UserRoles.Contains(user.UserRole)) { return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this Page"))); } /* STEP 19. Now we will create an authentication ticket, as the token is valid */ var identity = new ClaimsIdentity(validateToken.Claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(await Task.FromResult(AuthenticateResult.Success(ticket))); } catch (Exception ex) { Log.Error("An error occurred while seeding the database {Error} {StackTrace} {InnerException} {Source}", ex.Message, ex.StackTrace, ex.InnerException, ex.Source); return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized"))); } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Headers.ContainsKey(AuthorizationHeaderName)) { return(AuthenticateResult.NoResult()); } if (!AuthenticationHeaderValue.TryParse(Request.Headers[AuthorizationHeaderName], out AuthenticationHeaderValue headerValue)) { //Invalid Authorization header return(AuthenticateResult.NoResult()); } if (!BasicSchemeName.Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) { //Not Basic authentication header return(AuthenticateResult.NoResult()); } try { if (string.IsNullOrEmpty(headerValue.Parameter)) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidToken, "Invalid token"))); } byte[] headerValueBytes = Convert.FromBase64String(headerValue.Parameter); string userAndPassword = Encoding.UTF8.GetString(headerValueBytes); string[] parts = userAndPassword.Split(':'); if (parts.Length != 2) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidAutheHeader, "Invalid Basic authentication header"))); } string otherSystemName = parts[0]; string certificate = parts[1]; var os = await this._osRepository.FirstOrDefaultAsync(o => o.SystemName == otherSystemName && o.Certificate == certificate); if (os == null) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_RefuseAuthorization, "os is banish"))); } var user = await this._userRepository.SingleAsync(o => o.UserName == StaticRoleNames.Host.Admin && o.TenantId == null); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(AbpClaimTypes.UserName, StaticRoleNames.Host.Admin), new Claim("SplitPackageOtherSystemId", os.Id.ToString()) }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(AuthenticateResult.Success(ticket)); } catch (Exception ex) when(ex is FormatException || ex is DecoderFallbackException) { return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.Auth_InvalidToken, "Invalid token"))); } catch (Exception ex) { LogHelper.Logger.Error("application auth", ex); return(AuthenticateResult.Fail(new Abp.UI.UserFriendlyException((int)Split.Dto.ResultCode.SytemError, "Invalid auth request"))); } }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { if (Request.Method.Equals("get", StringComparison.InvariantCultureIgnoreCase) && !string.IsNullOrEmpty(Request.Uri.Query)) { var query = HttpUtility.ParseQueryString(Request.Uri.Query); if (query["bewit"] != null) { this.logger.WriteInformation(string.Format("Bewit found {0}", query["bewit"])); try { var principal = await Hawk.AuthenticateBewitAsync(query["bewit"], Request.Host.Value, Request.Uri, this.Options.Credentials); var identity = (ClaimsIdentity)((ClaimsPrincipal)principal).Identity; var ticket = new AuthenticationTicket(identity, null); return(ticket); } catch (SecurityException ex) { this.logger.WriteWarning("Unauthorized call. " + ex.Message); return(EmptyTicket()); } } } AuthenticationHeaderValue authorization = null; if (Request.Headers.ContainsKey("authorization")) { AuthenticationHeaderValue.TryParse(Request.Headers["authorization"], out authorization); } if (authorization != null && !string.Equals(authorization.Scheme, HawkAuthenticationOptions.Scheme)) { this.logger.WriteInformation(string.Format("Authorization skipped. Schema found {0}", authorization.Scheme)); return(EmptyTicket()); } if (authorization == null || string.IsNullOrWhiteSpace(authorization.Scheme)) { this.logger.WriteWarning("Authorization header not found"); return(EmptyTicket()); } else { if (string.IsNullOrWhiteSpace(authorization.Parameter)) { this.logger.WriteWarning("Invalid header format"); return(EmptyTicket()); } if (string.IsNullOrWhiteSpace(Request.Host.Value)) { this.logger.WriteWarning("Missing Host header"); return(EmptyTicket()); } Func <Task <string> > requestPayload = (async() => { var requestBuffer = new MemoryStream(); await Request.Body.CopyToAsync(requestBuffer).ConfigureAwait(false); requestBuffer.Flush(); Request.Body = requestBuffer; var payload = Encoding.UTF8.GetString(requestBuffer.ToArray()); return(payload); }); try { var principal = await Hawk.AuthenticateAsync(authorization.Parameter, Request.Host.Value, Request.Method, Request.Uri, this.Options.Credentials, this.Options.TimeskewInSeconds, requestPayload, Request.ContentType); var identity = (ClaimsIdentity)((ClaimsPrincipal)principal).Identity; var ticket = new AuthenticationTicket(identity, null); return(ticket); } catch (SecurityException ex) { this.logger.WriteWarning(ex.Message); return(EmptyTicket()); } } }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { if (!Request.Cookies.ContainsKey(AccessToken) || !Request.Cookies.ContainsKey(User_Id)) { Log.Error("No Access Token or User Id found"); return(await Task.FromResult(AuthenticateResult.NoResult())); } if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[AccessToken]}", out AuthenticationHeaderValue headerValue)) { Log.Error("Could not parse Token from Authentication Header"); return(await Task.FromResult(AuthenticateResult.NoResult())); } if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[User_Id]}", out AuthenticationHeaderValue headerValueUid)) { Log.Error("Could not parse User Id from Authentication Header"); return(await Task.FromResult(AuthenticateResult.NoResult())); } try { var key = Encoding.ASCII.GetBytes(_appSettings.Secret); var handler = new JwtSecurityTokenHandler(); TokenValidationParameters validationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, ValidateIssuer = true, ValidateAudience = true, ValidIssuer = _appSettings.Site, ValidAudience = _appSettings.Audience, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; var protectorProvider = _provider.GetService <IDataProtectionProvider>(); var protector = protectorProvider.CreateProtector(_dataProtectionKeys.ApplicationUserKey); var decryptedUid = protector.Unprotect(headerValueUid.Parameter); var decryptedToken = protector.Unprotect(headerValue.Parameter); TokenModel tokenModel = new TokenModel(); using (var scope = _provider.CreateScope()) { var dbContextService = scope.ServiceProvider.GetService <ApplicationDbContext>(); var userToken = dbContextService.Tokens.Include(x => x.User) .FirstOrDefault(UTF32Encoding => UTF32Encoding.UserId == decryptedUid && UTF32Encoding.User.UserName == Request.Cookies[Username] && UTF32Encoding.User.Id == decryptedUid && UTF32Encoding.User.UserRole == "Administrator"); tokenModel = userToken; } if (tokenModel == null) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized to view this page"))); } IDataProtector layerTwoProtector = protectorProvider.CreateProtector(tokenModel?.EncryptionKeyJwt); string decryptedTokenLayerTwo = layerTwoProtector.Unprotect(decryptedToken); var validateToken = handler.ValidateToken(decryptedTokenLayerTwo, validationParameters, out var securityToken); /* Checking Token Signature */ if (!(securityToken is JwtSecurityToken jwtSecurityToken) || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized"))); } var username = validateToken.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value; if (Request.Cookies[Username] != username) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized to view this page"))); } var user = await _userManager.FindByNameAsync(username); if (user == null) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized to view this page"))); } if (!UserRoles.Contains(user.UserRole)) { return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized to view this page"))); } var identity = new ClaimsIdentity(validateToken.Claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return(await Task.FromResult(AuthenticateResult.Success(ticket))); } catch (Exception ex) { Log.Error("An error occured while authenticating {Error} {StackTrace} {InnerException} {Source}", ex.Message, ex.StackTrace, ex.InnerException, ex.Source); return(await Task.FromResult(AuthenticateResult.Fail("Your are not authorized"))); } }
public bool Authenticate(HttpContext context, out HttpAuthenticationRequest request) { if (context.Request.Headers.TryGetValue("authorization", out var values) && values.Count == 1 && AuthenticationHeaderValue.TryParse( values[0], out var authenticationHeader) && authenticationHeader.Scheme == "Basic" && TryDecodeCredential(authenticationHeader.Parameter, out var username, out var password)) { request = new HttpAuthenticationRequest(context, username, password); _internalAuthenticationProvider.Authenticate(request); return(true); } request = null; return(false); }