我有一个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上运行该问题。
答案 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中读取了ValidIssuer
,Startup.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
下的环境变量初始化ValidIssuer
,CustomAuthController.cs
,signingKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
audience = $"https://{website}/";
issuer = $"https://{website}/";
,如下所示:
iss
使用jwt.io解码令牌,aud
和null
已更改,但我发现它仍然会返回401.我注意到我们都将生命周期设置为{{1}调用AppServiceLoginHandler.CreateToken
时。我试图用一个值(例如TimeSpan.FromDays(30))对它进行特定,然后它在天蓝色的一面工作。
总之,此问题可能是由于调用lifetime
时AppServiceLoginHandler.CreateToken
参数值所致,您需要在天蓝色方面设置特定值而不是null
。此外,您可以添加问题here以获得专业解释。
此外,您的移动后端将使用AppServiceTokenHandler.cs来处理安全令牌,您可以在使用TokenHandler
中间件时覆盖它并指定UseAppServiceAuthentication
参数,然后您可以调试令牌验证处理