目前,我正在使用OAuth和WebApi使用基于角色的身份验证对我的应用程序中的用户进行身份验证.我这样设置:
public override async Task GrantResourceOwnerCredentials (OAuthGrantResourceOwnerCredentialsContext context)
{
var user = await AuthRepository.FindUser(context.UserName, context.Password);
if (user === null)
{
context.SetError("invalid_grant", "The username or password is incorrect");
return;
}
var id = new ClaimsIdentity(context.Options.AuthenticationType);
id.AddClaim(New Claim(ClaimTypes.Name, context.UserName));
foreach (UserRole userRole in user.UserRoles)
{
id.AddClaim(new Claim(ClaimTypes.Role, userRole.Role.Name));
}
context.Validated(id);
}
使用< Authorize>保护我的API路线标签.
但是,我已经遇到了一个问题,我的用户可以为不同的客户端担任不同的角色.例如:
用户A可以与多个客户端关联:客户端A和客户端B.
当从任一客户端访问信息时,用户A可以具有不同的“角色”.因此,用户A可以是客户端A的管理员和客户端B的基本用户.
这意味着,以下示例:
[Authorize(Roles = "Admin")]
[Route("api/clients/{clientId}/billingInformation")]
public IHttpActionResult GetBillingInformation(int clientId)
{
...
}
用户A可以访问客户端A的帐单信息,但不能访问客户端B.
显然,我现在拥有的这种身份验证不起作用.设置客户端特定的基于角色的身份验证的最佳方法是什么?我可以简单地改变我现在拥有的东西,还是我必须完全以不同的方式设置它?
解决方法:
您可以删除authorize标记并在函数内部执行角色验证.
Lambda解决方案:
是否存在基于CustomerID和UserID添加的角色?
如果是这样,您可以执行类似下面示例的操作,根据您拥有的值获取客户,然后返回响应.
string userID = RequestContext.Principal.Identity.GetUserId();
var customer = Customer.WHERE(x => x.UserID == userID && x.clientId == clientId && x.Roles == '1')
您能否向我们提供有关您用于存储客户与用户之间的连接/角色的更多信息.
编辑:
以下是有关如何使用ActionFilterAttribute的示例.它从请求中获取CustomerId,然后从请求中获取标识的UserId.所以你可以用[UserAuthorizeAttribute]替换[Authorize]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class UserAuthorizeAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
try
{
var authHeader = actionContext.Request.Headers.GetValues("Authorization").First();
if (string.IsNullOrEmpty(authHeader))
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
Content = new StringContent("Missing Authorization-Token")
};
return;
}
ClaimsPrincipal claimPrincipal = actionContext.Request.GetRequestContext().Principal as ClaimsPrincipal;
if (!IsAuthoticationvalid(claimPrincipal))
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
Content = new StringContent("Invalid Authorization-Token")
};
return;
}
if (!IsUserValid(claimPrincipal))
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
Content = new StringContent("Invalid User name or Password")
};
return;
}
//Finally role has perpession to access the particular function
if (!IsAuthorizationValid(actionContext, claimPrincipal))
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
Content = new StringContent("Permission Denied")
};
return;
}
}
catch (Exception ex)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
Content = new StringContent("Missing Authorization-Token")
};
return;
}
try
{
//AuthorizedUserRepository.GetUsers().First(x => x.Name == RSAClass.Decrypt(token));
base.OnActionExecuting(actionContext);
}
catch (Exception)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
Content = new StringContent("Unauthorized User")
};
return;
}
}
private bool IsAuthoticationvalid(ClaimsPrincipal claimPrincipal)
{
if (claimPrincipal.Identity.AuthenticationType.ToLower() == "bearer"
&& claimPrincipal.Identity.IsAuthenticated)
{
return true;
}
return false;
}
private bool IsUserValid(ClaimsPrincipal claimPrincipal)
{
string userID = claimPrincipal.Identity.GetUserId();
var securityStamp = claimPrincipal.Claims.Where(c => c.Type.Equals("AspNet.Identity.SecurityStamp", StringComparison.OrdinalIgnoreCase)).Single().Value;
var user = _context.AspNetUsers.Where(x => x.userID.Equals(userID, StringComparison.OrdinalIgnoreCase)
&& x.SecurityStamp.Equals(securityStamp, StringComparison.OrdinalIgnoreCase));
if (user != null)
{
return true;
}
return false;
}
private bool IsAuthorizationValid(HttpActionContext actionContext, ClaimsPrincipal claimPrincipal)
{
string userId = claimPrincipal.Identity.GetUserId();
string customerId = (string)actionContext.ActionArguments["CustomerId"];
return AllowedToView(userId, customerId);
}
private bool AllowedToView(string userId, string customerId)
{
var customer = _context.WHERE(x => x.UserId == userId && x.CustomerId == customerId && x.RoleId == '1')
return false;
}
}