IdentityServer 4 - 使用隐式授权类型时向用户添加自定义声明
IdentityServer 4 - Adding a custom claim to a User when using Implicit grant type
我正在阅读 IdentityServer 4 教程,其中解释了如何使用 OpenID Connect 添加用户身份验证,可以在此处找到:
http://docs.identityserver.io/en/latest/quickstarts/3_interactive_login.html
基本上在本教程中,我们有一个 MVC 应用程序,其控制器操作装饰有授权属性。
每次用户尝试访问该操作时,如果 he/she 未登录,MVC 应用程序会将用户重定向到 Identity Server,以便 he/she 可以输入登录凭据。
如果凭据正确,Identity Server 将重定向回 MVC 应用程序,其中显示包含用户凭据的页面。
我已经结束了本教程,现在我想通过向令牌添加新的声明来进一步探索,但到目前为止我还没有成功。
在本教程中,通过在客户端配置上设置 AllowedScopes 添加范围 OpenId 和 Profile。
我试图创建一个 "age" 范围并以相同的方式添加它,但它没有用。
有谁知道我该怎么做?
代码如下所示(注释行是我已经尝试过的内容)。
IdentityServer 设置:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
在内存中存储配置:
public class Config
{
public static IEnumerable<Client> GetClients()
{
return new List<Client>()
{
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.Implicit,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
RequireConsent = false,
//AlwaysIncludeUserClaimsInIdToken = true,
//AlwaysSendClientClaims = true,
//AllowAccessTokensViaBrowser = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"age"
}
}
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>()
{
new TestUser()
{
SubjectId = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>()
{
new Claim("age", "15"),
new Claim("name", "Alice"),
new Claim("website", "https://alice.com")
}
},
new TestUser()
{
SubjectId = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>()
{
new Claim("age", "16"),
new Claim("name", "Bob"),
new Claim("website", "https://bob.com")
}
}
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource()
{
DisplayName = "Age",
Name = "age",
UserClaims = new List<string>()
{
"age"
}
}
};
}
}
MVC 应用程序配置:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddRazorViewEngine()
.AddAuthorization()
.AddJsonFormatters();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
});
}
MVC 应用程序声明页面:
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
这是登录成功后的结果:
西德
ba7ecb47f66524acce04e321b8d2c444
子
2
国内流离失所者
本地
姓名
鲍勃
如您所见,个人资料声明(名称和网站)出现了,但自定义 "age" 声明没有显示。
原始问题的答案是明确添加我们在设置 OpenId Connect 时要使用的声明。
我们需要在 .AddOpenIdConnect 方法中添加以下行:
options.Scope.Clear();
options.Scope.Add("age");
完整的设置如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddRazorViewEngine()
.AddAuthorization()
.AddJsonFormatters();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
options.Scope.Clear();
options.Scope.Add("age");
//Add all the claims you need
});
}
我正在阅读 IdentityServer 4 教程,其中解释了如何使用 OpenID Connect 添加用户身份验证,可以在此处找到:
http://docs.identityserver.io/en/latest/quickstarts/3_interactive_login.html
基本上在本教程中,我们有一个 MVC 应用程序,其控制器操作装饰有授权属性。 每次用户尝试访问该操作时,如果 he/she 未登录,MVC 应用程序会将用户重定向到 Identity Server,以便 he/she 可以输入登录凭据。 如果凭据正确,Identity Server 将重定向回 MVC 应用程序,其中显示包含用户凭据的页面。 我已经结束了本教程,现在我想通过向令牌添加新的声明来进一步探索,但到目前为止我还没有成功。 在本教程中,通过在客户端配置上设置 AllowedScopes 添加范围 OpenId 和 Profile。 我试图创建一个 "age" 范围并以相同的方式添加它,但它没有用。 有谁知道我该怎么做? 代码如下所示(注释行是我已经尝试过的内容)。
IdentityServer 设置:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
在内存中存储配置:
public class Config
{
public static IEnumerable<Client> GetClients()
{
return new List<Client>()
{
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.Implicit,
// where to redirect to after login
RedirectUris = { "http://localhost:5002/signin-oidc" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
RequireConsent = false,
//AlwaysIncludeUserClaimsInIdToken = true,
//AlwaysSendClientClaims = true,
//AllowAccessTokensViaBrowser = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"age"
}
}
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser>()
{
new TestUser()
{
SubjectId = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>()
{
new Claim("age", "15"),
new Claim("name", "Alice"),
new Claim("website", "https://alice.com")
}
},
new TestUser()
{
SubjectId = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>()
{
new Claim("age", "16"),
new Claim("name", "Bob"),
new Claim("website", "https://bob.com")
}
}
};
}
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource()
{
DisplayName = "Age",
Name = "age",
UserClaims = new List<string>()
{
"age"
}
}
};
}
}
MVC 应用程序配置:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddRazorViewEngine()
.AddAuthorization()
.AddJsonFormatters();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
});
}
MVC 应用程序声明页面:
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
这是登录成功后的结果:
西德 ba7ecb47f66524acce04e321b8d2c444
子 2
国内流离失所者 本地
姓名 鲍勃
如您所见,个人资料声明(名称和网站)出现了,但自定义 "age" 声明没有显示。
原始问题的答案是明确添加我们在设置 OpenId Connect 时要使用的声明。 我们需要在 .AddOpenIdConnect 方法中添加以下行:
options.Scope.Clear();
options.Scope.Add("age");
完整的设置如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddRazorViewEngine()
.AddAuthorization()
.AddJsonFormatters();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
options.Scope.Clear();
options.Scope.Add("age");
//Add all the claims you need
});
}