using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace HRD.LDAPService.JWT { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class JWTAuthorizeVendorId : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { if (JwtTokenConfig.AktivateAuthorizationFilter) { //allow access with logn & pwd and without Authorization token var path = context?.HttpContext.Request.Path.Value; if (!string.IsNullOrEmpty(path)) { if (JwtTokenConfig.IsInBlackList(path)) { context.Result = new JsonResult(new { message = $"Unauthorized access. Path is in a blacklist: '${path}'" }) { StatusCode = StatusCodes.Status403Forbidden }; return; } if (JwtTokenConfig.IsInWhiteList(path)) { return; } else //need jwt check { var check = (string)context.HttpContext.Items[JwtGlobals.HttpContextItem_IsValidHenselToken]; if (check == null) { context.Result = new JsonResult(new { message = $"Unauthorized access. Path: '${path}'" }) { StatusCode = StatusCodes.Status401Unauthorized }; return; } } var headerAuthorization = context.HttpContext.Request.Headers["Authorization"]; var authorizationType = headerAuthorization.FirstOrDefault()?.Split(" ").First(); if (authorizationType == null) { context.Result = new JsonResult(new { message = $"Eror. Path: '${path}'" }) { StatusCode = StatusCodes.Status401Unauthorized }; return; } var jwt = headerAuthorization.FirstOrDefault(); if (!JwtManager.IsValidatJwtTokenSubject(jwt)) { throw new UnauthorizedAccessException($"Not valid JWT"); } LdapUser ldapUser = JwtManager.DecryptTokenAsLdapUser(jwt); string ldapUserVendorId = ldapUser.GetExtendedAttributeValue("VendorId"); if (string.IsNullOrEmpty(ldapUserVendorId)) { context.Result = new JsonResult(new { message = $"Vendor Id is empty. Path: '${path}'" }) { StatusCode = StatusCodes.Status401Unauthorized }; return; } var syncIOFeature = context.HttpContext.Features.Get(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; var req = context.HttpContext.Request; req.EnableBuffering(); // read the body here as a workarond for the JSON parser disposing the stream if (req.Body.CanSeek) { req.Body.Seek(0, SeekOrigin.Begin); // if body (stream) can seek, we can read the body to a string for logging purposes using (var reader = new StreamReader( req.Body, encoding: Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 8192, leaveOpen: true)) { var jsonString = reader.ReadToEnd(); var content = JsonConvert.DeserializeObject(jsonString); if (content == null) { context.Result = new JsonResult(new { message = $"Unauthorized access. Can not deserialize the the Request: '${path}'" }) { StatusCode = StatusCodes.Status403Forbidden }; } if (content?.Root != null && string.Equals(content?.Root?.Type.ToString(), "Array", StringComparison.InvariantCulture)) { List contentList = JsonConvert.DeserializeObject>(jsonString); string jwtVendorId = contentList?.FirstOrDefault()?.vendorId; if (string.IsNullOrEmpty(jwtVendorId) || ldapUserVendorId != jwtVendorId) { context.Result = new JsonResult(new { message = $"Vendor {ldapUserVendorId} is not equal to Vendor from Token {jwtVendorId} List. Path: '${path}'" }) { StatusCode = StatusCodes.Status401Unauthorized }; return; } } else { string jwtVendorId = content.vendorId; if (string.IsNullOrEmpty(jwtVendorId) || ldapUserVendorId != jwtVendorId) { context.Result = new JsonResult(new { message = $"Vendor {ldapUserVendorId} is not equal to Vendor from Token {jwtVendorId}. Path: '${path}'" }) { StatusCode = StatusCodes.Status401Unauthorized }; return; } } } // Important! go back to beginning so json reader get's the whole thing req.Body.Seek(0, SeekOrigin.Begin); } } } } } } }