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

时间:2016-08-12 16:26:03

标签: entity-framework azure authentication owin azure-mobile-services

使用Xamarin表单的上述服务,我已启用OAuth(Microsoft和Google)身份验证。 API调用工作正常,具有[授权]的功能正在通过身份验证实施。

但是,在定义特定角色时,它会返回401错误。我正在尝试从 AuthorizationFilterAttribute 类创建自己的属性。

我将用户信息和角色存储在自定义表格中: UserProfile UserRoles 。因此,我不确定在哪里定义这些。因为它不从这些表中读取数据。如果我尝试运行以下命令,则返回空结果。

    [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事件未被命中,因此不确定如何解决此问题。

1 个答案:

答案 0 :(得分:1)

在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()的地方,您可以检查您的数据库并确定委托人是否有角色。