我有以下代码来设置Generic Principal。
public class AuthenticationHandler: DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var accessToken = request.Headers.Authorization;
if (accessToken == null)
return base.SendAsync(request, cancellationToken);
// Catch an error with regards to the accessToken being invalid
try
{
var formsAuthenticationTicket = FormsAuthentication.Decrypt(accessToken.Parameter);
if (formsAuthenticationTicket == null)
return base.SendAsync(request, cancellationToken);
var data = formsAuthenticationTicket.UserData;
var userData = JsonConvert.DeserializeObject<LoginRoleViewModel>(data);
var identity = new GenericIdentity(userData.Id.ToString(), "Basic");
var userRole = userData.Roles.ToArray();
var principal = new GenericPrincipal(identity, userRole);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
catch (Exception ex)
{
var responseMessage = request.CreateResponse(HttpStatusCode.BadRequest, new { ex.Message }); // return ex for full stacktrace
return Task<HttpResponseMessage>.Factory.StartNew(() => responseMessage);
}
return base.SendAsync(request, cancellationToken);
}
}
以下是控制器的示例
[Authorize(Roles = "Administrator, Customers")]
[HttpGet("customers/{id}")]
public CustomerViewModel GetCustomer(string id)
{
var param = AuthService.CheckPermission(Request, User, id);
var customer = Db.Customers.Find(param);
return Mapper.Map<CustomerViewModel>(customer);
}
这是我检查用户角色
的地方public int CheckPermission(HttpRequestMessage request, IPrincipal user, string param)
{
if (user.IsInRole("Customers") || user.IsInRole("Dealerships"))
{
if (param == null || param != "me")
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Forbidden, "unauthorized request"));
param = user.Identity.Name;
}
return Convert.ToInt32(param);
}
在升级到Web Api 2和MVC 5之前,这是完美的吗?现在用户没有任何角色或身份,有一些我不知道的改变了吗?
答案 0 :(得分:10)
不确定为什么它不再起作用,但在Web API 2中,有一个新的 HttpRequestContext
类 Principal
属性,这就是您应该设置为更新 Principal
的内容。您可以从请求中访问上下文对象。
答案 1 :(得分:6)
在多年的稳定性之后,真的不确定为什么这个功能发生了变化。
我们发现以下作品
request.GetRequestContext().Principal = new GenericIdentity(userData.Id.ToString(), "Basic");
这也有效,IMO在美学上更令人愉悦,因为你没有设置功能的成员
HttpContext.Current.User = new GenericIdentity(userData.Id.ToString(), "Basic");
答案 2 :(得分:3)
这就是我为了让它发挥作用所做的。升级导致这个问题是多么不幸。
var identity = new GenericIdentity("ApiUser", request.Headers.Authorization.Scheme);
var principal = new GenericPrincipal(identity, new string[0]);
request.GetRequestContext().Principal = principal;
答案 3 :(得分:0)
将“基本”更改为“表格”
var identity = new GenericIdentity(userData.Id.ToString(), "Forms");
此外,您使用的是FormsAuthenticationModule吗? MVC5通过此模块支持表单身份验证。检查此处给出的示例 http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationmodule.aspx
它建议使用FormsAuthentication_OnAuthenticate来描述和分配身份。