Dot Net Core Middleware (Authorization + Custom Authorize)
1. Add one helper class named AuthorizeHelper which contains GroupRoles static Dictionary, GroupRoles stored GroupId as key, and List of Roles against GroupId as Values.
a. GroupRoles Dictionary contains RoleId, RoleName, GroupName, GroupId, and Dictionary will static means it will need to store Group Id with Roles Once for all User and if one User will store that GroupId and Roles then other access that GroupId and Roles with DB call.
private static Dictionary<Int64, List<UsersGroup>> GroupRoles;
public class UsersGroup
2. Add SetRoles Static Method which is First Filter Group Ids which already have in Dictionary and then call DB for getting Roles from list of Group Id and then set that Roles by calling set method.{
public Int64 RoleId { get; set; } public Int64 GroupId { get; set; } public string GroupName { get; set; } public string RoleName { get; set; }
}
/// <summary>/// set Roles of Groups by getting Roles from Db and Set it in Dictionary/// </summary>/// <param name="Ids"></param>/// <param name="masterAPIService"></param>
public static void SetRoles(List<Int64> Ids, MasterAPIService masterAPIService)
{
if (GroupRoles != null) // check if Dictionary null or not{Ids = Ids.Where(x => !GroupRoles.ContainsKey(x)).ToList(); // filter GroupId, already exist Dictionary}if (Ids.Count > 0){// get Groups Role from Group Idvar AccessGroup = masterAPIService.GetRolesByGroup(Ids);// set Roles with Groupset(AccessGroup);}
3. Add set static Method which is initialized Dictionary if Dictionary will null and then set List of Roles as values of GroupId as Key. Set Method called from SetRole Method if Filtered List of Id length greater than 0.
}
/// <summary>
/// set Roles of Group
/// </summary>
/// <param name="userRoles"></param>
public static void set(List<UsersGroup> userRoles)
{
if (GroupRoles == null) // check id Dictionary is null or not{
GroupRoles = new Dictionary<long, List<UsersGroup>>();
}foreach (var role in userRoles) // loop to add Roles with Group{
if (GroupRoles.ContainsKey(role.GroupId)) // check id group id is already key of Dictionary{}else{}
}
}
GroupRoles[role.GroupId].Add(role); // add Role with old Group Id
GroupRoles[role.GroupId] = new List<UsersGroup>() { role }; // add Role with new Group Id
4. Add Get Static Method which is getting List of Roles from List of Group Id(which is got from token) from Static Dictionary.
/// <summary>
/// get list of Group Roles by Group Id
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public static List<UsersGroup> get(List<Int64> Id)
{
// return list of Roles from GroupId listreturn GroupRoles.Where(x => Id.Contains(x.Key)).SelectMany(x => x.Value).ToList();
2. Authorization Middleware:}
1. Add Middleware name AuthorizationMiddleware which is used for Role base Authentication using Middleware which is first to Get Controller and Action and Using AuthorizeHelper store GroupId and Roles common for all Users to reduce DB call and check if the user will Authorize for that API or not.
2. Need to Update startup.cs file by adding Middleware. app.UseMiddleware<AuthorizationMiddleware>();
3. Add Invoke Method in Authorization Middleware which is the First check if Get AccessToken API will be called if true then call next Middlarware by next_invoke method.
// check if get access token API call
if (context.Request.Path.Value.ToLower().Contains("security/getaccesstoken"))
{
await _next.Invoke(context); // call next middlewareReturn;
4. After If first Get Controller Name and Action Name for Called API by using Metadata of API context.}
// get controller and Action metadata
var controllerActionDescriptor = context
.GetEndpoint().Metadata.GetMetadata<ControllerActionDescriptor>();
// get controller name and action name
5. After that, Get UserId and List of Group assigned to that User from the token(from claims)var controllerName = controllerActionDescriptor != null ? controllerActionDescriptor.ControllerName : "";
var actionName = controllerActionDescriptor != null ? controllerActionDescriptor.ActionName : "";
// get UserId from token
Int64 UserId = Convert.ToInt64(context.User.Claims.FirstOrDefault(x => x.Type == "UserId")?.Value);
// get Group Ids from token
var groups = Array.ConvertAll((context.User.Claims.FirstOrDefault(x => x.Type == "GroupId")?.Value).Split(","), s => Convert.ToInt64(s)).ToList();
6. After that, Using AuthorizeHelper static Method First set a list of Roles For the List of GroupId and then get the List of Roles from the List of Group IDs by calling get the static Method of AuthorizeHelper.
// set new Roles with GroupId7. After getting AccessRole check if the user has access to calling API or not and if not then return 401 Unauthorize response with the response body.
AuthorizeHelper.SetRoles(groups,_masterAPIService);
// get Access Roles
var AccessRole = AuthorizeHelper.get(groups);
// check if the group has permission or not
if (AccessRole.Where(x => x.GroupName == controllerName && x.RoleName == actionName).Count() <= 0)
{
// create 401 responsevar response = new ResponseBody<string>(){
ResponseCode = Convert.ToInt32(HttpStatusCode.Unauthorized), ResponseStatus = HttpStatusCode.Unauthorized.ToString()
};string payload = "";payload = JsonConvert.SerializeObject(response);context.Response.ContentType = "application/json";context.Response.StatusCode = Convert.ToInt32(HttpStatusCode.Unauthorized);// write 401 responseawait context.Response.WriteAsync(payload);
3. (OR) CustomAuthorize Filter:}
1. Add CustomeAuthorize Attribute and get Arguments as Access Roles from Controller and Action Method and pass to Authorize Filter.
/// <summary>
/// Authorization Attribute
/// </summary>
public class CustomAuthorize : TypeFilterAttribute
{
public CustomAuthorize(string[] AccessRoles) : base(typeof(AuthorizationFilter)){
// add Argument as array of RolesArguments = new object[] { AccessRoles };
}
}
2. Add CustomeAuthorize Attribute and get Arguments as Access Roles from Controller and Action Method.
3. first Get UserId and List of Group assigned to that User from the token(from claims)
4. After that, Using AuthorizeHelper static Method First set a list of Roles For the List of GroupId and then get the List of Roles from the List of Group IDs by calling get the static Method of AuthorizeHelper.
if(context.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "EnvironmentId")?.Value != null)
{
5. After getting AccessRole check if the user has access to calling API or not and if not then return 401 Unauthorize response with the response body.// get UserId from tokenInt64 UserId = Convert.ToInt64(context.HttpContext.User.Claims.FirstOrDefault(x=> x.Type == "UserId")?.Value);// get GroupIds from tokenvar groups = Array.ConvertAll((context.HttpContext.User.Claims.FirstOrDefault(x=> x.Type == "GroupId")?.Value).Split(","), s => Convert.ToInt64(s)).ToList();// set new Groups RolesAuthorizeHelper.SetRoles(groups, _masterAPIService);// get Access Rolesvar AccessRole = AuthorizeHelper.get(groups);
if (Roles.Any(AccessRole.Select(x => x.RoleName).Contains))
{
Return;
}
}
//create 401 response
var response = new ResponseBody<string>()
{
ResponseCode = Convert.ToInt32(HttpStatusCode.Unauthorized), ResponseStatus = HttpStatusCode.Unauthorized.ToString()
};
context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.StatusCode =
Convert.ToInt32(HttpStatusCode.Unauthorized);
// write 401 response
context.Result = new UnauthorizedObjectResult(response); return;
}
Comments
Post a Comment