2017-11-18 187 views
0

我想使用Microsoft帐户作为IdentityServer4中的外部登录,我在Microsoft应用程序门户下创建了一个新应用程序并将其配置为以下:IdentityServer4 - 为输入参数'范围'提供的值无效。范围https://graph.microsoft.com/user.read电子邮件是无效的

  1. 我在委托权限添加新的网络平台
  2. 我添加了以下权限
    • User.Read
    • 电子邮件
    • 的OpenID
    • 简介

,这里是我使用的IdentityServer4通过添加电子邮件作为一个范围来访问Microsoft帐户代码:

services.AddAuthentication() 
    .AddMicrosoftAccount("MicrosoftAccount", options => 
    { 
     options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; 

     options.ClientId = "ClientId"; 
     options.ClientSecret = "ClientSecret"; 
     options.Scope.Add("email"); 

}); 

但在尝试访问Microsoft帐户我的时候出现以下错误

输入参数'scope'的提供值无效。范围https://graph.microsoft.com/user.read电子邮件无效

回答

1

使用OpenID Connect时,必须始终在请求的范围列表中包含openid。为了完整起见,这里的工作设置:

options.Scope.Add("openid"); 
options.Scope.Add("email"); 

这是微软here记载:

如果一个应用程序进行登入使用OpenID的连接,它必须要求OpenID的范围。

它实际上只是OpenID的spec的一部分:

ID连接请求必须包含的OpenID的范围值。如果openid范围值不存在,则行为完全未指定。其他范围值可以存在。应用程序无法理解的范围值应该被忽略。

默认情况下,ASP.NET核心only sets the user.read scope中的Microsoft帐户实现,这就是为什么您需要自己添加它。看起来,ASP.NET Core 中的Google实现默认为include the openid scope,这就解释了为什么您可能会看到不同提供者的不同结果。

鉴于您已将profile范围添加到“委托权限”列表中,您可能还想将其包含在请求的范围列表中。

这解释了您的错误原因,但更简单的方法可能是仅将请求的范围列表完全保留(仅使用user.read的默认值)。在我的例子中这样做,我仍然在我的例子中得到相同的索赔列表,它由nameidentifier,name,givenname,surnameemailaddress组成。这可以解释为什么默认情况下不请求OpenID特定范围。