Identityserver4 Identity Server 4:如何仅为UserInfoEndpoint添加自定义声明并在AccessToken中排除它们?

Identityserver4 Identity Server 4:如何仅为UserInfoEndpoint添加自定义声明并在AccessToken中排除它们?,identityserver4,claims,Identityserver4,Claims,我们希望从UserInfoEndPoint为用户声明中的大量数据提供服务,但不希望将这些声明嵌入AccessToken中 public async Task GetProfileDataAsync(ProfileDataRequestContext context) { if (context.Caller != IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken) { var sub

我们希望从UserInfoEndPoint为用户声明中的大量数据提供服务,但不希望将这些声明嵌入AccessToken中

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
   if (context.Caller != IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken)
   {
      var sub = context.Subject.GetSubjectId();

      // Get data from Db
      var claims = new List<Claim>();

      claims.Add(new Claim("global_company_id", "88888888-D964-4A2B-8D56-B893A5BCD700"));
      //..... add series of additional claims

      context.IssuedClaims = claims;
   }
}
据我所知,当我们想要保持AccessToken的小尺寸时,我们可以从UserInfoEndPoint返回额外的数据

因此,我按照以下方式实现了IProfileService:

public class ProfileService : IProfileService
{
    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();

        // Get data from Db
        var claims = new List<Claim>();

        claims.Add(new Claim("global_company_id", "88888888-D964-4A2B-8D56-B893A5BCD700"));
        //..... add series of additional claims

        context.IssuedClaims = claims;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var sub = context.Subject.GetSubjectId();

        context.IsActive = true;
    }
}
以下是我在Identity Server Provider中的客户端配置:

var clientUrl = "http://localhost:64177";
            return new Client
            {
                ClientName = "Test Web Application",
                ClientId = "testClientId",
                AllowedGrantTypes = GrantTypes.Hybrid,
                AllowOfflineAccess = false,
                RequireConsent = false,
                RedirectUris = new List<string>
                    {
                        $"{clientUrl}/signin-oidc"
                    },
                PostLogoutRedirectUris = new List<string>
                    {
                        $"{clientUrl}/signout-callback-oidc"
                    },
                AllowedScopes = new List<string>
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.OfflineAccess,
                        "t1_global_ids"
                    },
                ClientSecrets =
                    {
                        new Secret("abc123".Sha256())
                    }
            };
var clientUrl=”http://localhost:64177";
返回新客户端
{
ClientName=“测试Web应用程序”,
ClientId=“testClientId”,
AllowedGrantTypes=GrantTypes.Hybrid,
AllowOfflineAccess=false,
RequireSent=false,
重定向URI=新列表
{
$“{clientUrl}/signin oidc”
},
PostLogoutRedirectUris=新列表
{
$“{clientUrl}/signout回调oidc”
},
AllowedScopes=新列表
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.OfflineAccess,
“t1_全局_ID”
},
客户秘密=
{
新秘密(“abc123.Sha256())
}
};
这是我连接到Identity Server的MVC.Net核心客户端配置

services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies", options =>
            {
                options.AccessDeniedPath = "/AccessDenied";
            })
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = "http://identityserverUrl";
                options.ClientId = "testClientId";
                options.ResponseType = "code id_token";

                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("CustomClaims"); // <-- here

                options.SaveTokens = true;
                options.ClientSecret = "abc123";
                options.GetClaimsFromUserInfoEndpoint = true;

            });
services.AddAuthentication(选项=>
{
options.DefaultScheme=“Cookies”;
options.DefaultChallengeScheme=“oidc”;
})
.AddCookie(“Cookies”,选项=>
{
options.AccessDeniedPath=“/AccessDenied”;
})
.AddOpenIdConnect(“oidc”,选项=>
{
options.signnscheme=“Cookies”;
选项。权限=”http://identityserverUrl";
options.ClientId=“testClientId”;
options.ResponseType=“代码id\U令牌”;
options.Scope.Add(“openid”);
选项。范围。添加(“配置文件”);

options.Scope.Add(“CustomClaims”);//我曾经尝试过这个方法,并找到了一个解决方案,但它可能被认为是“黑客式的”——它确实有效,但我从未在生产中使用过,所以使用时要自担风险

ProfileService的GetProfileDataAsync()方法会在不同的时间被调用——当创建JWT时,当点击UserEndpoint时,等等。在这种情况下,您不希望在创建JWT时添加自定义声明,因此创建一个条件,当“调用者”是JWT创建过程(类型为“ClaimsProviderAccessToken”)

公共异步任务GetProfileDataAsync(ProfileDataRequestContext上下文) { if(context.Caller!=IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken) { var sub=context.Subject.GetSubjectId(); //从数据库获取数据 var索赔=新列表(); 添加(新索赔(“全球公司id”,“8888888-D964-4A2B-8D56-B893A5BCD700”); //……添加一系列附加权利要求 context.IssuedClaims=索赔; } }

有了这个,JWT不包含您的自定义声明,但如果您点击UserEndpoint,它将返回这些用户声明作为JSON的一部分。

我曾经尝试过这个方法,并找到了一个解决方案,但它可能被认为是“黑客的”——它起作用了,但我从未在生产中使用过,因此使用它的风险由您自己承担

ProfileService的GetProfileDataAsync()方法在不同的时间被调用——当创建JWT时,当点击UserEndpoint时,等等。在这种情况下,您不希望在创建JWT时添加自定义声明,因此创建一个条件,当“调用者”是JWT创建过程(类型为ClaimsProviderAccessToken”)

公共异步任务GetProfileDataAsync(ProfileDataRequestContext上下文) { if(context.Caller!=IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken) { var sub=context.Subject.GetSubjectId(); //从数据库获取数据 var索赔=新列表(); 添加(新索赔(“全球公司id”,“8888888-D964-4A2B-8D56-B893A5BCD700”); //……添加一系列附加权利要求 context.IssuedClaims=索赔; } } 这样,JWT就不包含您的自定义声明,但是如果您点击UserEndpoint,它会将这些用户声明作为JSON的一部分返回

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
   if (context.Caller != IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken)
   {
      var sub = context.Subject.GetSubjectId();

      // Get data from Db
      var claims = new List<Claim>();

      claims.Add(new Claim("global_company_id", "88888888-D964-4A2B-8D56-B893A5BCD700"));
      //..... add series of additional claims

      context.IssuedClaims = claims;
   }
}