I have a custom authorize attribute class to check isAuthorize
twice.
What I want :
1) It will check first if the user is super admin
or not. If he is , then he will be authorized
.
2) If he is not
, then it will check if he has a role named " Deal User
". If he is not
then he will be unauthorized
.
3) Now if the user is in
a " Deal User
" role , I want to check the user whether the user own the deal or not. So I check into database if the user owns that deal . If he owns
, then he will be authorized
. Otherwise he will be Unauthorized
.
public class DealManageCustomAuthorizeAttribute : AuthorizeAttribute
{
private static ApplicationDbContext Context = new ApplicationDbContext();
private static UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(Context);
private UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);
private enum Result
{
Authorize,
Unauthorize,
InternalServerError
}
public override void OnAuthorization(HttpActionContext actionContext)
{
var result = AuthorizeRequest(actionContext);
if (result == Result.Authorize)
{
return;
}
else
{
HandleUnauthorizedRequest(actionContext);
}
}
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//Code to handle unauthorized request
base.HandleUnauthorizedRequest(actionContext);
}
private Result AuthorizeRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
base.Roles = "Super Admin";
bool authorized = base.IsAuthorized(actionContext);
if (!authorized)
{
try
{
base.Roles = "Deal User";
bool auth = base.IsAuthorized(actionContext);
if (!auth)
{
return Result.Unauthorize;
}
Uri uri = actionContext.Request.RequestUri;
Guid dealId = new Guid(HttpUtility.ParseQueryString(uri.Query).Get("dealId"));
string userId = HttpContext.Current.User.Identity.GetUserId();
var retval = new Deal(Common.Common.TableSureConnectionString).CheckDealByIdAndUserId(dealId, userId);
if (retval)
{
return Result.Authorize;
}
return Result.Unauthorize;
}
catch (Exception)
{
return Result.InternalServerError;
}
}
return Result.Authorize;
}
}
I wrote the code and it is working. But I want to know whether it is the correct way to authorize users ?
It is unclear exactly why your custom authorize attribute is not working, but it is clear that its implementation is overly complex.
The AuthorizeAttribute
has simple boolean function IsAuthorized
that you can (and should) override to return whether or not the user is authorized. The base implementation already checks
so all you need to do is add additional logic when the user is in the Deal User role.
You should never access the static
HttpContext.Current
member in Web API/MVC. In this particular case, theactionContext
is being passed in as a parameter, which you can (and should) use.
using Microsoft.AspNet.Identity;
using System;
using System.Linq;
using System.Net.Http;
using System.Security.Principal;
using System.Web.Http;
using System.Web.Http.Controllers;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
public class DealManageCustomAuthorizeAttribute : AuthorizeAttribute
{
public DealManageCustomAuthorizeAttribute()
{
// Set the Super Admin and Deal User roles
this.Roles = "Super Admin,Deal User";
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// This checks whether the user is logged in, and whether
// they are in the Super Admin or Deal User role.
var isAuthorized = base.IsAuthorized(actionContext);
IPrincipal user = actionContext.ControllerContext.RequestContext.Principal;
// Special case - user is in the Deal User role
if (isAuthorized && user.IsInRole("Deal User"))
{
var queryString = actionContext.Request.GetQueryNameValuePairs()
.ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase);
// Ensure the query string contains the key "dealId"
if (!queryString.ContainsKey("dealId"))
{
return false;
}
Guid dealId;
if (!Guid.TryParse(queryString["dealId"], out dealId))
{
// If the Guid cannot be parsed, return unauthorized
return false;
}
// Now check whether the deal is authorized.
var userId = user.Identity.GetUserId();
return new Deal(Common.Common.TableSureConnectionString)
.CheckDealByIdAndUserId(dealId, userId);
}
return isAuthorized;
}
}
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.