2017-10-05 165 views
1

我有用于身份验证的Azure移动服务。我有一个自定义身份验证提供者,一旦证实,返回以下信息:401向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所以令牌不会过期。

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

我可以从天青日志看到这种情况的发生:

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', 操作= DefaultHttpControllerActivator.Create

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

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

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

2017-10-05T12:18:54 PID [5524]信息消息= '所选 格式化=' JsonMediaTypeFormatter',内容类型='应用/ JSON ; 字符集= UTF-8 '',操作= DefaultContentNegotiator.Negotiate

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

2017-10-05T12:18:54 PID [5524]信息 Operation = UserInfoController。ExecuteAsync,状态= 401(未授权)

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

可以看到,在授权属性被设定的401响应:

2017-10-05T12:18:54 PID [ 5524]信息 操作= AuthorizeAttribute.OnAuthorizationAsync,状态= 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与用户的相匹配,并且AuthToken与我的登录方法中返回的AutToken相同。

是否还有其他需要设置/可以启用对Azure移动服务的已验证请求?

感谢

编辑 因为我已经禁用了Azure的所有其他认证提供但这并没有解决问题。 我也在本地调试了代码,并且只有在部署到Azure时,我的本地主机上才会运行该问题。

回答

2

根据您的代码,您使用的是Azure移动应用程序的自定义身份验证。正如Adrian大厅关于Custom Authentication的书:

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

此外,我建议你只使用邮递员或小提琴手来模拟对您的API端点的要求,你需要添加一个新的X-ZUMO-AUTH头和值设置为AuthToken缩小这个问题。此外,您可以在本地检查此问题,然后使用令牌模拟请求以查看您的代码是否可以在您身边工作,或者这是天蓝色方面的问题。对于您的客户,您可以使用client.LoginAsync("custom", JObject.FromObject(user))进行日志记录,而不需要自己设置CurrentUser。欲了解更多详情,你可以关注阿德里安大厅的书来检查这个问题。

UPDATE:

根据您的意见,我测试了它在我的身边。我在本地和天蓝色的一面使用了中间件UseAppServiceAuthentication,并从我的网站上阅读了SigningKey,ValidAudience,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() 
    }); 
} 

注:我在Azure上启用身份验证/授权。对于我的CustomAuthController.cs,我将AppServiceLoginHandler.CreateToken与我的web.config中的设置一起初始化为UseAppServiceAuthentication中间件。在设置后,它可以按照预期在我的身边和天蓝色的一面工作。

然后我禁用了UseAppServiceAuthentication中间件部署到天蓝色的一面。正如你所提到的,我遇到过401,我认为令牌验证可能会失败。我复查Custom Authentication,发现你需要初始化SigningKeyValidAudienceValidIssuer从环境变量在你CustomAuthController.cs如下:

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

使用jwt.io令牌进行解码,在issaud已经改变,但我发现它仍然会返回401.我注意到,当调用AppServiceLoginHandler.CreateToken时,我们都将终身设置为null。我试图用一个值来指定它(例如TimeSpan.FromDays(30)),然后它在azure方面工作。

总之,当调用AppServiceLoginHandler.CreateToken时,此问题可能是由于lifetime参数值造成的,因此您需要在azure端设置特定值而不是null。此外,您可以添加您的问题here专业解释。

此外,行动后端将使用AppServiceTokenHandler.cs处理安全令牌,你可以使用UseAppServiceAuthentication中间件的时候,那么你可以调试令牌验证处理覆盖它和具体的TokenHandler参数。

+0

我能想到的唯一的事情是我打开了Facebook身份验证提供程序,因为我的应用程序还提供了FB登录。但是,我仍然可以使用我的自定义身份验证登录,它只是对发生故障的服务提出的后续请求。我尝试过使用fiddler并得到相同的{“message”:“授权已被拒绝。”}响应。 – LDJ

+0

您的自定义autodapicontroller可以匿名访问,而此问题的控制器具有'Authorize'属性。您可以尝试暂时移除FB提供商以缩小此问题的范围。另外,请尝试在本地运行您的服务器端项目,然后尝试检查自定义身份验证是否可以在本地运行。 –

+0

嗨布鲁斯,我已经删除了FB提供程序,并得到相同的结果,401未经授权的错误。有没有办法更好地理解为什么它的未经授权? – LDJ