代码之家  ›  专栏  ›  技术社区  ›  xhedgepigx

Azure Mobile Client自定义身份验证无法访问具有[授权]属性的控制器

  •  0
  • xhedgepigx  · 技术社区  · 6 年前

    我正在上使用具有自定义授权的Azure Mobile Service客户端 Xamarin.Forms 站台

    登录使用 .LoginAsync("custom", user) 由于返回 MobileServiceUser 具有非null MobileAuthenticationToken UserId 并自动连接 <MobileServiceClient>.CurrentUser 具有该值。

    然而,每当我尝试提出进一步的请求时(登录后立即),我都会得到一个 MobileServiceInvalidOperationException .. (Unauthorized) 当我检查 CurrentUser 价值-它仍然是一样的。

    我是不是错过了什么 MobileServiceClient ? 我的理解是,如果 .CurrentUser 然后,它将在标题中包含它作为 X-ZUMO-AUTH 标题。

    服务器登录:

    [Route(".auth/login/custom")]
    public class AuthController : ApiController
    {
        private readonly AppContext _context;
    
        private readonly string
            _singningKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
    
        private readonly string
            _audience;
    
        private readonly string
            _issuer;
    
        public AuthController()
        {
            _context = new AppContext();
    
            var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
            _audience = $"https://{website}/";
            _issuer = $"https://{website}/";
        }
    
        public HttpResponseMessage Post([FromBody] LoginUser body)
        {
            if (body?.Username == null || body.Password == null || body.Username.Length == 0 || body.Password.Length == 0)
            {
                return Request.CreateUnauthorizedResponse();
            }
    
            if (!IsValidUser(body))
            {
                return Request.CreateUnauthorizedResponse();
            }
    
            var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, body.Username) };
    
            var token = AppServiceLoginHandler.CreateToken(claims,
                    _singningKey,
                    _audience,
                    _issuer,
                    TimeSpan.FromHours(24));
    
            return Request.CreateResponse(HttpStatusCode.OK, new LoginResult
            {
                AuthenticationToken = token.RawData,
                User = new LoginResultUser() { UserId = body.Username }
            });
        }
    
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _context.Dispose();
            }
            base.Dispose(disposing);
        }
    
        private bool IsValidUser(LoginUser user)
        {
            .. this works fine
        }
    }
    
    public class LoginUser
    {
        [JsonProperty("username")]
        public string Username { get; set; }
        [JsonProperty("password")]
        public string Password { get; set; }
    }
    
    public class LoginResultUser
    {
        [JsonProperty("userId")]
        public string UserId { get; set; }
    }
    
    public class LoginResult
    {
        [JsonProperty("authenticationToken")]
        public string AuthenticationToken { get; set; }
        [JsonProperty("user")]
        public LoginResultUser User { get; set; }
    }
    

    客户端登录:

    var database = new MobileServiceClient(BackendApiServerAddress);
    var result = await database.LoginAsync("custom", JObject.FromObject(user)); //this sets database.CurrentUser to a MobileServiceUser with MobileAuthenticationToken and UserId and returns the value
    await database.SyncContext.PushAsync(); // this fails
    

    例外情况:

    {Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: The request could not be completed.  (Unauthorized)
      at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient+<ThrowInvalidResponse>d__24.MoveNext () [0x001ec] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient+<SendRequestAsync>d__26.MoveNext () [0x000fc] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient+<RequestAsync>d__18.MoveNext () [0x000fa] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.MobileServiceTable+<ReadAsync>d__20.MoveNext () [0x000a3] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.MobileServiceTable+<ReadAsync>d__18.MoveNext () [0x00141] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.Sync.PullAction+<ProcessTableAsync>d__14.MoveNext () [0x0015c] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.Sync.TableAction+<ExecuteAsync>d__29.MoveNext () [0x002a5] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.Sync.MobileServiceSyncContext+<ExecuteSyncAction>d__34.MoveNext () [0x0008e] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at Microsoft.WindowsAzure.MobileServices.Sync.MobileServiceSyncContext+<PullAsync>d__30.MoveNext () [0x0039b] in <42e24ce875d34485ad11c4f8aebb904a>:0 
    --- End of stack trace from previous location where exception was thrown ---
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <3fd174ff54b146228c505f23cf75ce71>:0 
      at FRAOffline.Backend.Database.DbContext+<SyncCustomersAsync>d__32.MoveNext () [0x00049] in C:\Users\Heather\Documents\Visual Studio 2017\Projects\FRAOffline\FRAOffline\FRAOffline\Backend\Database\Customers.DbContext.cs:83 }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Bruce Chen    6 年前

    根据您的描述,您的自定义身份验证可以验证客户端用户并生成 authenticationToken 成功地我建议您检查身份验证/授权设置,并确保设置 请求未通过身份验证时要采取的操作 允许请求(无操作) 在Azure移动应用程序的“设置验证/授权”下。此外,我建议您利用 fiddler 调用时捕获网络跟踪 await database.SyncContext.PushAsync() . 此外,还可以使用postman对表控制器模拟请求,如下所示,以缩小此问题:

    GET https://{your-app-name}.azurewebsites.net/tables/{table-name}
    Header x-zumo-auth:{authenticationToken}
    

    此外,你还可以阅读阿德里安·霍尔的书 Custom Authentication Authentication in the Backend .