azure - 向 Azure 移动服务发出请求时出现 401 未经授权

标签 azure authentication azure-mobile-services

我有一个 Azure 移动服务,用于进行身份验证。我有一个自定义身份验证提供程序,一旦经过验证,它会返回以下信息:

JwtSecurityToken token = AppServiceLoginHandler.CreateToken(claims, signingKey, audience, issuer, null);
return Ok(new LoginResult()
{
  AuthenticationToken = token.RawData,
  User = signinedInUser,
  StatusCode = System.Net.HttpStatusCode.OK
});

请注意,Timespan 设置为 null,因此 token 不会过期。

然后,我向 AMS 发出后续请求,该 AMS 具有受 Authorize() 属性保护的 Controller 。然而,在我的任何断点被命中之前,这些都失败了,并出现 401 Unauthorized 响应。

我可以从 Azure 日志中看到发生这种情况的位置:

2017-10-05T12:18:54 PID[5524] Information Request, Method=POST, Url=https://mywebsite.azurewebsites.net/api/userinfo/update, Message='https://mywebsite.azurewebsites.net/api/userinfo/update'

2017-10-05T12:18:54 PID[5524] Information Message='UserInfo', Operation=DefaultHttpControllerSelector.SelectController

2017-10-05T12:18:54 PID[5524] Information Message='MyAMS.Controllers.UserInfoController', Operation=DefaultHttpControllerActivator.Create

2017-10-05T12:18:54 PID[5524] Information Message='MyAMS.Controllers.UserInfoController', Operation=HttpControllerDescriptor.CreateController

2017-10-05T12:18:54 PID[5524] Information Message='Selected action 'Update(User cpUser)'', Operation=ApiControllerActionSelector.SelectAction

2017-10-05T12:18:54 PID[5524] Information Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance

2017-10-05T12:18:54 PID[5524] Information Message='Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate

2017-10-05T12:18:54 PID[5524] Information Operation=AuthorizeAttribute.OnAuthorizationAsync, Status=401 (Unauthorized)

2017-10-05T12:18:54 PID[5524] Information Operation=UserInfoController.ExecuteAsync, Status=401 (Unauthorized)

2017-10-05T12:18:54 PID[5524] Information Response, Status=401 (Unauthorized), Method=POST, Url=https://mywebsite.azurewebsites.net/api/userinfo/update, Message='Content-type='application/json; charset=utf-8', content-length=unknown'

您可以看到 Authorize 属性正在设置 401 响应:

2017-10-05T12:18:54 PID[5524] Information Operation=AuthorizeAttribute.OnAuthorizationAsync, Status=401 (Unauthorized)

在客户端上,我填充了用户 ID 和身份验证 token :

this.client = new MobileServiceClient("https://mywebsite.azurewebsites.net");
var user = UserProfileService.GetCurrentSignedInUser();
client.CurrentUser = new MobileServiceUser(user.UserId.ToString())
{
    MobileServiceAuthenticationToken = user.AuthToken
};

单步执行代码,我已确认 UserID 与用户的 ID 匹配,并且 AuthToken 与我的登录方法中返回的 AutToken 相同。

我还需要设置/执行其他操作才能启用对 Azure 移动服务的经过身份验证的请求吗?

谢谢

编辑 此后,我禁用了 Azure 中的所有其他身份验证提供程序,但这并没有解决问题。 我还在本地调试了代码,并且仅在部署到 Azure 时才在我的本地主机上运行时不会出现此问题。

最佳答案

根据您的代码,您正在为您的 Azure 移动应用程序使用自定义身份验证。正如阿德里安·霍尔 (Adrian Hall) 的书所述 Custom Authentication :

You must turn on Authentication / Authorization in your App Service. Set the Action to take when request is not authenticated to Allow Request (no action) and do not configure any of the supported authentication providers.

此外,我建议您只使用 postman 或 fiddler 来模拟针对 api 端点的请求,您需要添加一个新的 X-ZUMO-AUTH header 并将值设置为 AuthToken 可以缩小这个问题的范围。另外,您可以在本地检查此问题,然后使用 token 模拟请求,看看您的代码是否可以在您这边工作,或者这是 azure 方面的问题。对于您的客户端,您可以使用 client.LoginAsync("custom", JObject.FromObject(user)) 进行日志记录,而无需自行设置 CurrentUser。更多详情,您可以按照adrian Hall的书来查看这个问题。

更新:

根据您的评论,我在我这边进行了测试。我在本地端和 azure 端都使用了 UseAppServiceAuthentication 中间件,并读取了 SigningKeyValidAudienceValidIssuer从我的 Startup.MobileApp.cs 下的 web.config 中,如下所示:

//if (string.IsNullOrEmpty(settings.HostName))
{
    app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
    {
        // This middleware is intended to be used locally for debugging. By default, HostName will
        // only have a value when running in an App Service application.
        SigningKey = ConfigurationManager.AppSettings["SigningKey"],
        ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
        ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
        TokenHandler = config.GetAppServiceTokenHandler()
    });
}

注意:我在 azure 上启用了身份验证/授权。对于我的 CustomAuthController.cs,我使用 web.config 中的设置调用了 AppServiceLoginHandler.CreateToken 作为初始化的 UseAppServiceAuthentication 中间件。经过设置,它可以在我这边和 azure 那边按预期工作。

然后,我在部署到 Azure 端时禁用 UseAppServiceAuthentication 中间件。正如您提到的,我遇到了 401,我认为 token 验证可能会失败。我重新检查了Custom Authentication并发现您需要从 CustomAuthController.cs 下的环境变量初始化 SigningKeyValidAudienceValidIssuer 作为如下:

signingKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
audience = $"https://{website}/";
issuer = $"https://{website}/";

使用jwt.io为了解码 token ,issaud 已更改,但我发现它仍然会返回 401。我注意到我们都将生存期设置为 null 当调用AppServiceLoginHandler.CreateToken时。我尝试用一​​个值(例如 TimeSpan.FromDays(30))来指定它,然后它可以在 azure 方面工作。

综上所述,此问题可能是由于调用AppServiceLoginHandler.CreateToken时的lifetime参数值导致的,您需要设置一个特定的值,而不是null 在 azure 的一侧。此外,您可以添加您的问题 here寻求专业解释。

此外,您的移动后端将使用 AppServiceTokenHandler.cs为了处理安全 token ,您可以在使用 UseAppServiceAuthentication 中间件时覆盖它并指定 TokenHandler 参数,然后您可以调试 token 验证处理。

关于azure - 向 Azure 移动服务发出请求时出现 401 未经授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46586383/

相关文章:

Azure AD B2C 自定义策略 - Javascript

database - 跟踪 S0 Azure SQL 数据库资源使用情况的单位有哪些?

python - 从 Azure 函数获取托管身份访问 token 时出错

java - 在可用时,通过 Active Directory 使用单点登录进行身份验证的最佳方法是什么?

asp.net - 清除缓存后,set-cookie 不适用于 IE11/10

node.js - Azure 移动应用程序迁移后出现故障

javascript - Azure 移动服务 : Custom Authentication using Java script backend?

c# - 如何从 ASP.NET Core 应用程序访问 Azure Active Directory 的其他数据?

c# - ASP.NET 登录状态 : logout not working

rest - 是否有针对 Azure 移动服务的调度程序运行一次的 REST API 调用?