0

Xamarin 양식에 위와 같은 서비스를 사용하면 OAuth (Microsoft 및 Google) 인증을 사용하도록 설정했습니다. API 호출이 제대로 작동하고 [권한 부여] 기능이 인증을 통해 시행됩니다.Azure 모바일 앱 서비스 역할 승인이 작동하지 않습니다.

그러나 특정 역할을 정의 할 때 401 오류를 반환합니다. 내 자신의 특성을 AuthorizationFilterAttribute 클래스에서 만들려고합니다. USERPROFILEUserRoles :

내 사용자 정의 테이블에서 사용자 정보와 역할을 저장하고있다. 따라서, 나는 이들을 어디에서 정의 할 지 모르겠습니다. 이후 이들 테이블에서 데이터를 읽지 않습니다. 다음을 실행하려고하면 빈 결과가 반환됩니다.

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

나는 웹 API를 기반으로 전역에서 온 가장 가까운 기사 : Web Api 2 and Owin

편집 아드리안 의해 답변을 바탕으로, 나는 코드를 다음, 아직 같은 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

Azure 모바일 애플리케이션에서 EntityFramework를 사용하고 있습니다. 원하는 모든 쿼리를 수행 할 수 있습니다. 여기 AAD 자격 증명에 의해 반환 주장을 확인하는 예제 AuthorizationFilterAttribute은 다음과 같습니다

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

당신은 모델로 사용할 수 있습니다

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

이 특정 버전이 같은 일을 할 수 있습니다. GetAppServiceIdentityAsync()을 확인하면 대신 데이터베이스를 확인하고 주체에 역할이 있는지 여부를 결정할 수 있습니다.

+0

위에서 시도했지만 행운이 없습니다. 401 오류가 여전히 발생하고 이벤트가 실행되지 않아 로컬에서 디버깅 할 수 없습니다. –

+0

내 코드의 일부 수정 및 작동 : var identity = actionContext.ControllerContext.RequestContext.Principal.Identity as ClaimsIdentity; Claim identityClaim = identity.Claims.FirstOrDefault (c => c.Type == ClaimTypes.NameIdentifier); var user = db.UserProfiles.FirstOrDefault (x => x.User_ID.EndsWith (identityClaim.Value)); ' –

관련 문제