125 lines
6.3 KiB
C#

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<IHttpBodyControlFeature>();
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<dynamic>(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<dynamic> contentList = JsonConvert.DeserializeObject<List<dynamic>>(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);
}
}
}
}
}
}
}