Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使IdentityServer向访问令牌添加用户标识?_C#_Asp.net Web Api_Identityserver4_Access Token_Identityserver3 - Fatal编程技术网

C# 如何使IdentityServer向访问令牌添加用户标识?

C# 如何使IdentityServer向访问令牌添加用户标识?,c#,asp.net-web-api,identityserver4,access-token,identityserver3,C#,Asp.net Web Api,Identityserver4,Access Token,Identityserver3,简短:我的客户端从IdentityServer示例服务器检索访问令牌,然后将其传递给我的WebApi。在我的控制器中,this.HttpContext.User.GetUserId()返回null(但用户有其他声明)。我怀疑访问令牌中没有nameidentity声明。如何使IdentityServer包含它 到目前为止,我所尝试的: 从混合流切换到隐式流(随机尝试) 在IdSvrHost范围定义中,我添加了 索赔={new ScopeClaim(ClaimTypes.NameIdentifie

简短:我的客户端从IdentityServer示例服务器检索访问令牌,然后将其传递给我的WebApi。在我的控制器中,this.HttpContext.User.GetUserId()返回null(但用户有其他声明)。我怀疑访问令牌中没有nameidentity声明。如何使IdentityServer包含它

到目前为止,我所尝试的:

  • 从混合流切换到隐式流(随机尝试)
  • 在IdSvrHost范围定义中,我添加了

    索赔={new ScopeClaim(ClaimTypes.NameIdentifier,alwaysInclude:true)}

  • 在IdSvrHost客户端定义中,我添加了

    索赔={新索赔(ClaimTypes.NameIdentifier,“42”)}

(也是一次随机尝试)

我还尝试了范围定义中的其他范围,但它们都没有出现。似乎nameidentity通常包含在identity token中,但对于我所知道的大多数公共API,您不向服务器提供identity token

更多详情: IdSrvHost和Api位于不同的主机上。 控制器已[授权]。事实上,我可以看到其他索赔。 Api配置为

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

app.UseIdentityServerAuthentication(options => {
    options.Authority = "http://localhost:22530/";

    // TODO: how to use multiple optional scopes?
    options.ScopeName = "borrow.slave";
    options.AdditionalScopes = new[] { "borrow.receiver", "borrow.manager" };

    options.AutomaticAuthenticate = true;
    options.AutomaticChallenge = true;
});
范围:

public static Scope Slave { get; } = new Scope {
    Name = "borrow.slave",
    DisplayName = "List assigned tasks",
    Type = ScopeType.Resource,

    Claims = {
        new ScopeClaim(ClaimTypes.NameIdentifier, alwaysInclude: true),
    },
};
客户:

new Client {
    ClientId = "borrow_node",
    ClientName = "Borrow Node",

    Flow = Flows.Implicit,

    RedirectUris = new List<string>
    {
        "borrow_node:redirect-target",
    },

    Claims = { new Claim(ClaimTypes.NameIdentifier, "42") },

    AllowedScopes = {
        StandardScopes.OpenId.Name,
        //StandardScopes.OfflineAccess.Name,
        BorrowScopes.Slave.Name,
    },
}
我也试过了

request.CreateAuthorizeUrl(
            clientId: "borrow_node",
            responseType: "id_token token",
            scope: "openid borrow.slave",
            redirectUri: "borrow_node:redirect-target",
            state: state,
            nonce: nonce);

万岁,当我偶然发现这一页时,我找到了答案:

显然,用户身份是在访问令牌的“sub”声明中传递的。因为我盲目地复制了API示例,所以它的配置包括

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

这实际上阻止了我的API将“sub”声明映射到nameidentifier。删除这一行后,经过身份验证的控制器的HttpContext.User.GetUserId()将正确返回用户ID。

如果您不确定access\u令牌中有什么,请复制并粘贴到jwt.io中,然后查看该声明。下面是我在access\u令牌中得到的内容:{“iss”:“aud”:“exp”:1460323801,“nbf”:1460320201,“client\u ID”:“borrow\u node”,“scope:“borrow.slave”,“sub:“88421113”,“auth_time:”1460320200,“idp:”idsvr“}-没有nameidentity claimBTW,我不希望nameidentity为“42”,这只是试图看看这是否会改变什么。检查了IdentityServer源代码(未调试):这一行似乎会过滤掉nameidentity:var claims=FilterProtocolClaims(context.IssuedClaims);行位于DefaultClaimsProvider.cs中。根据设计,access_令牌似乎不包括IdentityServer中的用户标识。如果是这样,我是否必须将id_令牌和access_令牌都传递给API端点?如何使用Bear实现这一点?
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();