I have the following code to set a 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);
}
}
Below is an example of a controller
[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);
}
And this is where I check if the user roles
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);
}
This was working perfectly before upgrading to Web Api 2 and MVC 5? Now the User has no roles or identity, has something changed that I am unaware of?
Not sure why it doesn't work anymore, but in Web API 2, there is a new class HttpRequestContext with a Principal property, and that is what you should be setting to update the Principal. You can access the context object from the request.
Really uncertain as to why this functionality has changed after years of stability.
We found the following works
request.GetRequestContext().Principal = new GenericIdentity(userData.Id.ToString(), "Basic");
This also works and IMO is more aesthetically pleasing as you're not setting members of a function
HttpContext.Current.User = new GenericIdentity(userData.Id.ToString(), "Basic");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With