Using above service with Xamarin form, I have enable authentication with OAuth (Microsoft and Google). API call are working fine and those functions with [Authorize], are being enforced with authentication.
However, when defining specific role, it returns 401 error. I'm trying to create my own attribute from AuthorizationFilterAttribute class.
I'm storing the user info and roles in my custom tables : UserProfile and UserRoles. Hence, I'm not sure where to define these. Since its not reading data from these tables. If I try to run following, it returns empty result.
[Authorize]
[HttpGet]
public IHttpActionResult Roles()
{
ClaimsIdentity claimsId = ClaimsPrincipal.Current.Identity as ClaimsIdentity;
var appRoles = new List<String>();
foreach (Claim claim in ClaimsPrincipal.Current.FindAll(claimsId.RoleClaimType))
appRoles.Add(claim.Value);
return Ok(appRoles);
}
The closest article I came across in based on Web API : Web Api 2 and Owin
Edit Based on answer by Adrian, I added following code, but yet getting same 401 error.
public class MyAuthorize : System.Web.Http.Filters.AuthorizationFilterAttribute
{
private string[] accessRoleNames;
public MyAuthorize(params string[] roleNames)
{
accessRoleNames = roleNames;
}
public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
try
{
await Task.Delay(100);
OnAuthorization(actionContext);
}
catch (Exception)
{
throw;
}
}
public override void OnAuthorization(HttpActionContext actionContext)
{
WMSEntities db = new WMSEntities();
string userID = actionContext.ControllerContext.RequestContext.Principal.Identity.Name;
var user = db.UserProfiles.FirstOrDefault(x => x.User_ID == userID);
if (user == null)
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
else
{
bool ok = false;
foreach (var item in user.AppRoles)
{
foreach (string ar in accessRoleNames)
{
if (item.Name == ar)
ok = true;
}
}
db.Dispose();
if (!ok)
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
base.OnAuthorization(actionContext);
}
}
And referencing to my function as follows :
[MyAuthorize(UserRole.Admin, UserRole.Collector)]
[HttpGet]
[Route("GetDataAdmin")]
public string GetDataAdmin()
{
return "success access GetDataAdmin";
}
If I debug the code locally, the OnAuthorization events are not being hit , hence not sure how to troubleshoot this.