public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { RequestHeaders headers = context.HttpContext.Request.GetTypedHeaders(); AuthenticationHeaderValue authentication = headers.Get <AuthenticationHeaderValue>("DiagnosticServicesAuthorization"); if (authentication == null) { context.Result = Unauthorized("Authentication is required."); return; } if (authentication.Scheme != "Bearer") { context.Result = Forbidden("'Bearer' is the only supported authorization scheme."); return; } string token = authentication.Parameter; if (string.IsNullOrEmpty(token)) { context.Result = Forbidden("Token is missing."); return; } try { TokenContract tokenContract = _tokenService.ValidateSecurityToken(token); // TODO: Validate it contains the expected app Id too. if (!tokenContract.PermissionLevel.HasFlag(_permissionLevel)) { context.Result = Forbidden($"Insufficient permission level: {tokenContract.PermissionLevel}"); return; } context.HttpContext.Features.Set <ProfilerContext>(new ProfilerContext() { AppId = tokenContract.AppId }); } catch (SecurityTokenExpiredException ex) { _logger.LogError(ex, "Token expired."); context.Result = Forbidden(ex.Message); } catch (Exception ex) { _logger.LogError(ex, "Token validation error"); context.Result = Forbidden(ex.Message); } // TODO: Is async op needed? await Task.CompletedTask; }
public IActionResult Get(string subscriptionId, string resourceGroupName, string componentName) { // TODO: Get AppId somehow var appId = new Guid("9c7614fa-c798-4219-9b92-31a938ac91b9"); TokenContract tokenContract = new TokenContract() { AppId = appId, // TODO, get appId from CDS, PermissionLevel = PermissionLevel.ReadOnly, }; string token = _profilerTokenService.IssueSecurityToken(tokenContract); return(Ok(new { token })); }
public string IssueSecurityToken(TokenContract basedOn) { DateTime accessExpiration = DateTime.UtcNow.Add(TokenExpiry); var appIdString = basedOn.AppId.ToString("D", CultureInfo.InvariantCulture); JwtSecurityToken jwtToken = new JwtSecurityToken( issuer: "ApplicationInsightsProfiler", audience: appIdString, claims: new[] { new Claim(ClaimTypes.PermissionLevel, ((int)basedOn.PermissionLevel).ToString()), new Claim(ClaimTypes.AppId, appIdString), }, expires: accessExpiration, signingCredentials: new SigningCredentials( key: new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_signingKeyProvider.SigningKey)), algorithm: SecurityAlgorithms.HmacSha256) ); return(_tokenHandler.WriteToken(jwtToken)); }
public TokenContract ValidateSecurityToken(string accessToken) { ClaimsPrincipal claims = GetSecurityTokenClaims(accessToken); string permissionLevelNumberInString = claims.FindFirstValue(ClaimTypes.PermissionLevel); if (int.TryParse(permissionLevelNumberInString, out int permissionLevelInInt)) { PermissionLevel permissionLevel = (PermissionLevel)permissionLevelInInt; TokenContract tokenContract = new TokenContract() { AppId = new Guid(claims.FindFirstValue(ClaimTypes.AppId)), PermissionLevel = permissionLevel, }; return(tokenContract); } else { throw new InvalidOperationException($"Unrecognized permission level enum value: {permissionLevelNumberInString}"); } }