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

时间:2017-10-05 13:05:32

标签: azure authentication azure-mobile-services

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

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,因此令牌不会过期。

然后我向我的AMS发出后续请求,该请求具有受Authorize()属性保护的控制器。但是,在我的任何断点被击中之前,这些都是401 Unauthorized响应失败。

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

  

2017-10-05T12:18:54 PID [5524]信息请求,方法= POST,   URL = https://mywebsite.azurewebsites.net/api/userinfo/update,   消息=' https://mywebsite.azurewebsites.net/api/userinfo/update'

     

2017-10-05T12:18:54 PID [5524]信息消息=' UserInfo',   操作= DefaultHttpControllerSelector.SelectController

     

2017-10-05T12:18:54 PID [5524]信息   消息=' MyAMS.Controllers.UserInfoController&#39 ;,   操作= DefaultHttpControllerActivator.Create

     

2017-10-05T12:18:54 PID [5524]信息   消息=' MyAMS.Controllers.UserInfoController&#39 ;,   操作= HttpControllerDescriptor.CreateController

     

2017-10-05T12:18:54 PID [5524]信息消息='选择的操作   '更新(用户cpUser)'',   操作= ApiControllerActionSelector.SelectAction

     

2017-10-05T12:18:54 PID [5524]信息消息='将使用相同的信息   ' JsonMediaTypeFormatter'格式化&#39 ;,   操作= JsonMediaTypeFormatter.GetPerRequestFormatterInstance

     

2017-10-05T12:18:54 PID [5524]信息消息='已选择   formatter =' JsonMediaTypeFormatter',content-type =' application / json;   charset = utf-8'',Operation = DefaultContentNegotiator.Negotiate

     

2017-10-05T12:18:54 PID [5524]信息   Operation = AuthorizeAttribute.OnAuthorizationAsync,Status = 401   (未授权)

     

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

     

2017-10-05T12:18:54 PID [5524]信息响应,状态= 401   (未经授权),Method = POST,   URL = https://mywebsite.azurewebsites.net/api/userinfo/update,   消息='内容类型='应用/ JSON;字符集= UTF-8&#39 ;,   内容长度=未知'

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

  

2017-10-05T12:18:54 PID [5524]信息   Operation = AuthorizeAttribute.OnAuthorizationAsync,Status = 401   (未授权)

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

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时才会在我的localhost上运行该问题。

1 个答案:

答案 0 :(得分:2)

根据您的代码,您正在为您的azure移动应用使用自定义身份验证。正如adrian hall的关于Custom Authentication的书:

  

您必须在App Service中启用身份验证/授权。将请求未经过身份验证时采取的操作设置为允许请求(无操作),并且不要配置任何支持的身份验证提供程序。

此外,我建议您只使用postman或fiddler模​​拟针对您的api端点的请求,您需要添加一个新的AuthToken标头并将值设置为client.LoginAsync("custom", JObject.FromObject(user))以缩小此问题。此外,您可以在本地检查此问题,然后使用令牌模拟请求,以查看您的代码是否可以在您身边工作,或者这是天蓝色方面的问题。对于您的客户,您可以使用CurrentUser进行日志记录,而无需自行设置UseAppServiceAuthentication。有关详细信息,您可以按照adrian hall的书来检查此问题。

<强>更新

根据你的评论,我在我身边进行了测试。我在本地和天蓝色方面使用了SigningKey中间件,并从ValidAudience下的web.config中读取了ValidIssuerStartup.MobileApp.cs//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() }); } 作为如下:

CustomAuthController.cs

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

然后我在部署到azure侧时禁用SigningKey中间件。我提到了401,我认为令牌验证可能会失败。我重新检查了Custom Authentication,发现您需要从ValidAudience下的环境变量初始化ValidIssuerCustomAuthController.cssigningKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY"); var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"); audience = $"https://{website}/"; issuer = $"https://{website}/"; ,如下所示:

iss

使用jwt.io解码令牌,audnull已更改,但我发现它仍然会返回401.我注意到我们都将生命周期设置为{{1}调用AppServiceLoginHandler.CreateToken时。我试图用一个值(例如TimeSpan.FromDays(30))对它进行特定,然后它在天蓝色的一面工作。

总之,此问题可能是由于调用lifetimeAppServiceLoginHandler.CreateToken参数值所致,您需要在天蓝色方面设置特定值而不是null。此外,您可以添加问题here以获得专业解释。

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