.net core Microsoft Graph API userInfo端点未知错误:令牌必须包含子声明

.net core Microsoft Graph API userInfo端点未知错误:令牌必须包含子声明,.net-core,azure-active-directory,microsoft-graph-api,openid-connect,.net Core,Azure Active Directory,Microsoft Graph Api,Openid Connect,我正在尝试使用通过Open ID Connect接收的访问令牌在处执行userinfo端点 收到的答复是: 400错误请求 { "error": { "code": "UnknownError", "message": "Token must contain sub claim.", "innerError": {

我正在尝试使用通过Open ID Connect接收的访问令牌在处执行userinfo端点

收到的答复是:

400错误请求

{
    "error": {
        "code": "UnknownError",
        "message": "Token must contain sub claim.",
        "innerError": {
            "date": "2021-02-22T07:14:37",
            "request-id": "650a2928-b0e7-49ae-9e6d-ecb569ee69e6",
            "client-request-id": "650a2928-b0e7-49ae-9e6d-ecb569ee69e6"
        }
    }
}
访问令牌有效,并且不包含子声明

如果我登录到,并使用它自动检索的访问令牌,它将对同一用户起作用。但是,子索赔是不同的,有两种

似乎来自OIDC的令牌没有正确的子声明-这是怎么回事

直接从/授权端点[工作]访问令牌:

来自OIDC的访问令牌[不工作]:

OIDC配置:
options.Authority = authority;
options.ClientId = Configuration[ConfigKeys.IdentityProvider.ClientID];
options.ClientSecret = Configuration[ConfigKeys.IdentityProvider.ClientSecret];

options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.CallbackPath = Configuration[ConfigKeys.IdentityProvider.CallbackPath];
options.SignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;

options.CorrelationCookie.Expiration
    = options.NonceCookie.Expiration
    = options.ProtocolValidator.NonceLifetime
    = options.RemoteAuthenticationTimeout
    = TimeSpan.FromHours(8);

options.Resource = "https://graph.microsoft.com";
options.GetClaimsFromUserInfoEndpoint = false;
options.UseTokenLifetime = true;
options.RequireHttpsMetadata = true;
options.SaveTokens = true;

options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("offline_access");
options.Scope.Add("groups");

options.RemoteAuthenticationTimeout = TimeSpan.FromHours(10);
options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuer = true,
    ValidIssuer = authority,
    //NameClaimType = "name"
};
访问令牌有效,并且不包含子声明

我想您没有正确获取令牌,请按照以下步骤操作

一,

2.在广告应用程序的
API权限
中,在Microsoft Graph中添加以下权限

3.在
认证
中,选择以下选项

4.在浏览器中点击下面的URL,替换您的
,登录您的用户帐户,然后您将获得一个
访问令牌
和一个
id\u令牌

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>&response_type=token+id_token&redirect_uri=http://localhost&scope=user.read+openid+profile+email&response_mode=fragment&state=12345&nonce=678910
https://login.microsoftonline.com//oauth2/v2.0/authorize?client_id=&response_type=token+id\u令牌和重定向\u uri=http://localhost&scope=user.read+openid+profile+email&response\u mode=fragment&state=12345&nonce=678910
5.使用
access\u令牌调用
https://graph.microsoft.com/oidc/userinfo
endpoint,它工作正常,
sub
值在我的示例中为
ey4uo7uc1ig2n8ebealb4ldxj1nu8nuc2jxzgkisn4

6.解码中步骤4中获得的
id_令牌
sub
也是
EY4uO7uc1IG2n8EboEalB4LDxJ1NU8nuc2JXZgkisN4
,因此它表示从
https://graph.microsoft.com/oidc/userinfo
端点是正确的

如果我登录到,并使用它自动检索的访问令牌,它将对同一用户起作用。但是,子索赔是不同的,有两种

您从Microsoft Graph Explorer获得的令牌是一个
access\u令牌
,第一个
sub
access\u令牌
的值,第二个是您想要的,即
id\u令牌
sub

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>&response_type=token+id_token&redirect_uri=http://localhost&scope=user.read+openid+profile+email&response_mode=fragment&state=12345&nonce=678910

似乎来自OIDC的令牌没有正确的子声明-这是怎么回事

这是正确的,正如我上面提到的,您从OIDC获得的
sub
与从
id\u令牌获得的
sub
相同

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id>&response_type=token+id_token&redirect_uri=http://localhost&scope=user.read+openid+profile+email&response_mode=fragment&state=12345&nonce=678910
参考-

这些值与应用程序将在发布给应用程序的中看到的值相同

注意:您可能会发现手动获取的
sub
与从MS Graph Explorer获取的第二个
sub
不同,这是因为您的用户帐户登录了两个不同的客户端,一个是Graph Explorer的客户端,另一个是您的自定义广告应用程序

参考-

更新:


OIDC不使用v2.0端点,为了解决此问题,我们需要配置OIDC以使其使用v2.0端点,只需在配置的
权限中添加
v2.0

您是否解析令牌以查看它?是的-您提供的信息非常好,但它还没有工作。我设置了以前没有的Graph API权限,然后使用tenantid和clientid参数从/authorize端点获得了一个访问令牌——这很有效。与来自OIDC的访问令牌相比较,它包含相同的访问令牌'sub',但不包含id\u令牌'sub'-它不起作用。@user3167162您能详细说明一下这一点吗
与来自OIDC的访问令牌相比较,它包含相同的访问令牌'sub',但不包含id\u令牌'sub'
?也许有一些快照在里面?您是否从
/authorize
端点获取了
访问\u令牌
id\u令牌
?您使用哪个令牌调用
/oidc/userinfo
?我检索了两个访问令牌,并针对
/oidc/userinfo
端点对它们进行了测试:一个直接来自
/authorize
端点,正如您所指示的-它可以工作。第二个到
OIDC
-不起作用。请参阅上面的其他信息。@user3167162在
权限中添加
v2.0
@user3167162 Done。