I'm working on a set of web services. I've implemented a custom OWIN authentication based on my company's security, so now the Authorize attribute works.
[Authorize]// It's working!
I want to package it up for others, but I want to support roles first (or at least have a plan/recommendation for how to support roles). Unfortunately, my company doesn't have a standard way of handling roles, so different services (or applications) may take different approaches.
[Authorize("Member")]// It's not working. :(
What is the best approach to make my authentication middleware easily extensible? My particular needs are geared towards supporting roles, but something more generic is fine. Some thoughts I've had:
I'm inclined towards the latter approach, but I'm really just shooting in the dark. I'd greatly appreciate a confident confirmation of what would work or has worked best.
To support a custom attribute like [Authorize("Member")] you can extend the attributes and write a custom one. Extend the System.Web.Http.AuthorizeAttribute class and perform all checks your need to do.
This explains how to do it:
https://www.codeproject.com/Tips/376810/ASP-NET-WEB-API-Custom-Authorize-and-Exception-Han
And this is an implementation in our solution.
public class ClaimsAuthorize : System.Web.Mvc.AuthorizeAttribute
{
public string PhenixPermissions { get; set; }
public string[] NeededPermissions;
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
Logger.Logger.Trace("ClaimsAuthorize.AuthorizeCore");
NeededPermissions = PhenixPermissions.Split(',');
if (!(httpContext.User.Identity is ClaimsIdentity))
{
return false;
}
var claimsIdentity = httpContext.User.Identity as ClaimsIdentity;
Claim encodedPermissions = claimsIdentity.FindFirst(ConfigurationManager.AppSettings["ApplicationPermissionsKey"]);
string applicationId = ClaimsHelper.GetClaimValue("audience");
if (encodedPermissions == null)
{
Logger.Logger.Warn("No PhenixPermissions found. Are you logged in?");
return false;
}
var tenant = AppManager.GetApplication(applicationId);
List<string> decodedPermissions = PermissionsDecodeHelper.BitDecodePermissions(tenant.ConnectionString, encodedPermissions.Value);
bool hasRights = false;
foreach (var neededPermission in NeededPermissions)
{
if (decodedPermissions.FirstOrDefault(x => x == neededPermission) != null)
{
Logger.Logger.Debug(string.Format("User '{0}' authorized to access view '{1}'.", claimsIdentity.Name.ToString(), httpContext.Request.FilePath));
hasRights = true;
}
}
return hasRights;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
Logger.Logger.Trace("ClaimsAuthorize.HandleUnauthorizedRequest");
Logger.Logger.Warn(string.Format("Unauthorized to access '{0}'.", filterContext.Controller));
filterContext.Controller.TempData["ErrorCode"] = "0123456789";
filterContext.Controller.TempData["ErrorMessage"] = string.Format("'{0}' is not authorized to access access view '{1}'", HttpContext.Current.User.Identity.Name.ToString(), filterContext.Controller);
filterContext.Result = new RedirectResult("~/Home/Error");
}
}
Some remarks: the PhenixPermissions is the string that comes in when using the attribute like [ClaimsAuthorize(PhenixPermissions = "ConsultExternalLink")]
The rest is some specific logic for our application but you should get it.
Just return AuthorizeCore true or false when allowed to call the Controller, API, etc...
Hope this helps
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.