Azure 移动应用服务角色授权不起作用
Azure Mobile App Service Role Authorization Not Working
通过 Xamarin 表单使用上述服务,我启用了 OAuth 身份验证(Microsoft 和 Google)。 API 调用工作正常,那些带有 [Authorize] 的函数正在通过身份验证强制执行。
但是,定义特定角色时,returns401错误。我正在尝试从 AuthorizationFilterAttribute class.
创建我自己的属性
我将用户信息和角色存储在我的自定义表中:UserProfile 和 UserRoles。因此,我不确定在哪里定义这些。因为它不从这些表中读取数据。如果我尝试 运行 以下,它会 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()
的地方,您可以改为检查您的数据库并确定委托人是否有角色。
通过 Xamarin 表单使用上述服务,我启用了 OAuth 身份验证(Microsoft 和 Google)。 API 调用工作正常,那些带有 [Authorize] 的函数正在通过身份验证强制执行。
但是,定义特定角色时,returns401错误。我正在尝试从 AuthorizationFilterAttribute class.
创建我自己的属性我将用户信息和角色存储在我的自定义表中:UserProfile 和 UserRoles。因此,我不确定在哪里定义这些。因为它不从这些表中读取数据。如果我尝试 运行 以下,它会 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()
的地方,您可以改为检查您的数据库并确定委托人是否有角色。