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