Azure 移动应用服务角色授权不起作用

Azure Mobile App Service Role Authorization Not Working

通过 Xamarin 表单使用上述服务,我启用了 OAuth 身份验证(Microsoft 和 Google)。 API 调用工作正常,那些带有 [Authorize] 的函数正在通过身份验证强制执行。

但是,定义特定角色时,returns401错误。我正在尝试从 AuthorizationFilterAttribute class.

创建我自己的属性

我将用户信息和角色存储在我的自定义表中:UserProfileUserRoles。因此,我不确定在哪里定义这些。因为它不从这些表中读取数据。如果我尝试 运行 以下,它会 returns 空结果。

    [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);
    }

我在基于 Web API 中遇到的最接近的文章:Web Api 2 and Owin

编辑 根据 Adrian 的回答,我添加了以下代码,但仍然出现相同的 401 错误。

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);
    }
}

并参考我的函数如下:

    [MyAuthorize(UserRole.Admin, UserRole.Collector)]
    [HttpGet]
    [Route("GetDataAdmin")]
    public string GetDataAdmin()
    {
        return "success access GetDataAdmin";
    }

如果我在本地调试代码,则不会触发 OnAuthorization 事件,因此不确定如何解决此问题。

在 Azure 移动应用中,您正在使用 EntityFramework。您可以对此进行任何查询。下面是一个 AuthorizationFilterAttribute 示例,它检查 AAD 凭据返回的声明:

using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Microsoft.Azure.Mobile.Server.Authentication;

namespace Backend.Helpers
{
    public class AuthorizeClaimsAttribute : AuthorizationFilterAttribute
    {
        string Type { get; }
        string Value { get; }

        public AuthorizeClaimsAttribute(string type, string value)
        {
            Type = type;
            Value = value;
        }

        public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            var request = actionContext.Request;
            var user = actionContext.RequestContext.Principal;
            if (user != null)
            {
                var identity = await user.GetAppServiceIdentityAsync<AzureActiveDirectoryCredentials>(request);
                var countOfMatchingClaims = identity.UserClaims
                    .Where(c => c.Type.Equals(Type) && c.Value.Equals(Value))
                    .Count();
                if (countOfMatchingClaims > 0) return;

            }
            throw new HttpResponseException(HttpStatusCode.Unauthorized);
        }
    }
}

此特定版本允许您执行以下操作:

[AuthorizeClaims("groups","some-object-id")]

你可以以此为范本。在我检查 GetAppServiceIdentityAsync() 的地方,您可以改为检查您的数据库并确定委托人是否有角色。