Web API 的基于角色的身份验证无法正常工作
Role Based Authentication for web API not working
我在使用基于角色的 Web 身份验证时遇到问题 APi。
我有一个控制器 class,其中控制器有一个名为 Myauthorize 的自定义授权属性。
我在控制器中有一个方法,只能通过管理员访问才能访问。
但同样的方法也一直在调用 QA 访问权限。
有人可以帮忙解决以下问题吗?
请在下面找到代码。
控制器:
namespace Hosiptal.Controllers.office
{
[MyAuthorize(Constants.Roles.Admin)]
public class UserRolesController : ApiController
{
private readonly IRepository<EntityModels.Role> rolesRepository;
public UserRolesController(IRepository<EntityModels.Role> rolesRepository)
{
this.rolesRepository = rolesRepository;
}
// GET: Users
[HttpGet]
[Route("")]
public IEnumerable<Role> GetAll()
{
return this.rolesRepository.GetAll()
.ToArray()
.Select(r => Mapper.Current.Get<Role>(r));
}
}
}
MyAuthorize 已关注。
namespace Hospital.Web.Filters.WebApi
{
public class MyAuthorize: AuthorizeAttribute
{
private readonly string[] allowedroles;
private static IUserProfileRepository UserProfileRepository
{
get { return IoC.Current.Resolve<IUserProfileRepository>(); }
}
public MyAuthorize(params string[] roles)
{
this.allowedroles = roles;
}
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken
cancellationToken)
{
var claimsIdentity = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;
var alias = claimsIdentity.Name.Split('@')[0];
if (alias == null)
{
throw new ArgumentNullException(nameof(actionContext));
}
user(alias);
return base.OnAuthorizationAsync(actionContext, cancellationToken);
}
public static GenericPrincipal user(string userName)
{
userName = userName.ToUpper();
var userProfile = UserProfileRepository.Get(userName) ?? new UserProfile()
{
UserName = userName,
Roles = new List<Role>(),
FirstLoginDateUtc = DateTime.UtcNow
};
return CreatePrincipal(userProfile);
}
public static GenericPrincipal CreatePrincipal(UserProfile user)
{
var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name,
user.UserName) }, "Custom");
return new GenericPrincipal(identity, user.Roles.Select(i =>
i.Name).ToArray());
}
}
}
如何根据访问级别限制此处的用户?
这对我有用
public class AdminAuthorizeAttributee : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (AuthorizeRequest(actionContext))
{
return;
}
HandleUnauthorizedRequest(actionContext);
}
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
base.HandleUnauthorizedRequest(actionContext);
}
private bool AuthorizeRequest(HttpActionContext actionContext)
{
try
{
var username = HttpContext.Current.User.Identity.Name;
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = userManager.Users.Where(a => a.UserName == username).FirstOrDefault();
var rolesForUser = userManager.GetRoles(user.Id);
var role = "Admin";
if (rolesForUser.Contains(role))
{
return true;
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
并在控制器中
[AdminAuthorizeAttributee]
public class YOUR_Controller : ApiController
您不需要为此创建自己的授权过滤器。
使用 built-in [Authorize(Roles = "Admin")]
- 这将检查用户是否有一个名为“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”的声明,以及该值是否与您输入的值匹配在该授权属性中,授权将成功。
所以在你的情况下,只要确保当你登录用户时,他的声明设置为这样的角色:
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Role, "Admin"), //here set the users role
// ... other claims
};
(ClaimTypes
class 来自命名空间 System.Security.Claims
)
然后 [Authorize(Roles = "Admin")]
应该可以正常工作
如果您查看 the source code 的 AuthorizeAttribute
class,您将看到它使用控制器上下文请求的主体来执行授权,因此重写 IsAuthorized
方法相反,将您的代码移到那里并将您创建的主体分配给上下文请求的主体:
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var claimsIdentity = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;
var alias = claimsIdentity.Name.Split('@')[0];
if (alias == null)
{
throw new ArgumentNullException(nameof(actionContext));
}
//This sets the context's principal so the base class code can validate
actionContext.ControllerContext.RequestContext.Principal = user(alias);
//Call the base class and let it work its magic
return base.IsAuthorized(actionContext);
}
我不会对设计本身发表评论。这应该可以解决您的问题。
我在使用基于角色的 Web 身份验证时遇到问题 APi。
我有一个控制器 class,其中控制器有一个名为 Myauthorize 的自定义授权属性。 我在控制器中有一个方法,只能通过管理员访问才能访问。 但同样的方法也一直在调用 QA 访问权限。 有人可以帮忙解决以下问题吗?
请在下面找到代码。 控制器:
namespace Hosiptal.Controllers.office
{
[MyAuthorize(Constants.Roles.Admin)]
public class UserRolesController : ApiController
{
private readonly IRepository<EntityModels.Role> rolesRepository;
public UserRolesController(IRepository<EntityModels.Role> rolesRepository)
{
this.rolesRepository = rolesRepository;
}
// GET: Users
[HttpGet]
[Route("")]
public IEnumerable<Role> GetAll()
{
return this.rolesRepository.GetAll()
.ToArray()
.Select(r => Mapper.Current.Get<Role>(r));
}
}
}
MyAuthorize 已关注。
namespace Hospital.Web.Filters.WebApi
{
public class MyAuthorize: AuthorizeAttribute
{
private readonly string[] allowedroles;
private static IUserProfileRepository UserProfileRepository
{
get { return IoC.Current.Resolve<IUserProfileRepository>(); }
}
public MyAuthorize(params string[] roles)
{
this.allowedroles = roles;
}
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken
cancellationToken)
{
var claimsIdentity = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;
var alias = claimsIdentity.Name.Split('@')[0];
if (alias == null)
{
throw new ArgumentNullException(nameof(actionContext));
}
user(alias);
return base.OnAuthorizationAsync(actionContext, cancellationToken);
}
public static GenericPrincipal user(string userName)
{
userName = userName.ToUpper();
var userProfile = UserProfileRepository.Get(userName) ?? new UserProfile()
{
UserName = userName,
Roles = new List<Role>(),
FirstLoginDateUtc = DateTime.UtcNow
};
return CreatePrincipal(userProfile);
}
public static GenericPrincipal CreatePrincipal(UserProfile user)
{
var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name,
user.UserName) }, "Custom");
return new GenericPrincipal(identity, user.Roles.Select(i =>
i.Name).ToArray());
}
}
}
如何根据访问级别限制此处的用户?
这对我有用
public class AdminAuthorizeAttributee : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (AuthorizeRequest(actionContext))
{
return;
}
HandleUnauthorizedRequest(actionContext);
}
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
base.HandleUnauthorizedRequest(actionContext);
}
private bool AuthorizeRequest(HttpActionContext actionContext)
{
try
{
var username = HttpContext.Current.User.Identity.Name;
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = userManager.Users.Where(a => a.UserName == username).FirstOrDefault();
var rolesForUser = userManager.GetRoles(user.Id);
var role = "Admin";
if (rolesForUser.Contains(role))
{
return true;
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
并在控制器中
[AdminAuthorizeAttributee]
public class YOUR_Controller : ApiController
您不需要为此创建自己的授权过滤器。
使用 built-in [Authorize(Roles = "Admin")]
- 这将检查用户是否有一个名为“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”的声明,以及该值是否与您输入的值匹配在该授权属性中,授权将成功。
所以在你的情况下,只要确保当你登录用户时,他的声明设置为这样的角色:
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Role, "Admin"), //here set the users role
// ... other claims
};
(ClaimTypes
class 来自命名空间 System.Security.Claims
)
然后 [Authorize(Roles = "Admin")]
应该可以正常工作
如果您查看 the source code 的 AuthorizeAttribute
class,您将看到它使用控制器上下文请求的主体来执行授权,因此重写 IsAuthorized
方法相反,将您的代码移到那里并将您创建的主体分配给上下文请求的主体:
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var claimsIdentity = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;
var alias = claimsIdentity.Name.Split('@')[0];
if (alias == null)
{
throw new ArgumentNullException(nameof(actionContext));
}
//This sets the context's principal so the base class code can validate
actionContext.ControllerContext.RequestContext.Principal = user(alias);
//Call the base class and let it work its magic
return base.IsAuthorized(actionContext);
}
我不会对设计本身发表评论。这应该可以解决您的问题。