[英]IdentityServer4 client for Password Flow not including TestUser claims in access token
我正在嘗試使用 IdentityServer4 中的(舊版)資源所有者密碼流創建一個沙盒應用程序。 我用這些包建立了一個全新的 ASP.NET Core 3 項目:
<PackageReference Include="IdentityServer4" Version="3.1.3" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
我正在使用以下啟動部分:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(new[] { new ApiResource("foo-api") })
.AddInMemoryIdentityResources(new[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
new IdentityResource("role", new[] { JwtClaimTypes.Role }),
})
.AddInMemoryClients(new[]
{
new Client
{
// Don't use RPO if you can prevent it. We use it here
// because it's the easiest way to demo with users.
ClientId = "legacy-rpo",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowAccessTokensViaBrowser = false,
RequireClientSecret = false,
AllowedScopes = { "foo-api", "openid", "profile", "email", "role" },
},
})
.AddTestUsers(new List<TestUser>
{
new TestUser
{
SubjectId = "ABC-123",
Username = "john",
Password = "secret",
Claims = new[]
{
new Claim(JwtClaimTypes.Role, "user"),
new Claim(JwtClaimTypes.Email, "john@example.org"),
new Claim("x-domain", "foo") },
},
})
然后我提供一個 static index.html
文件,該文件調用/connect/token
端點,如下所示:
const response = await fetch("/connect/token", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: new URLSearchParams({
"grant_type": "password",
"client_id": "legacy-rpo",
"username": "john",
"password": "secret",
// scope omitted should net *all* scopes in IDS4
}),
});
但它返回給我一個 access_token(已解碼),如下所示:
{
"nbf": 1588582642,
"exp": 1588586242,
"iss": "https://localhost:5001",
"aud": "foo-api",
"client_id": "legacy-rpo",
"sub": "ABC-123",
"auth_time": 1588582642,
"idp": "local",
"scope": [
"email",
"openid",
"profile",
"role",
"foo-api"
],
"amr": [
"pwd"
]
}
我缺少電子郵件、角色等作為access_token
中的頂級條目。
在挖掘源代碼時,我看到TestUsers 的 ProfileService應該通過擴展方法將所有請求的聲明添加到令牌。 我在谷歌搜索我的問題時發現的大多數問題要么是我已經做過的(或嘗試過的,見下文),要么是關於其他邊緣情況。
許多其他線程也導致Dominick Baier 關於角色的帖子,但問題是API 方面不識別角色。 我的問題是該role
根本不包含在令牌中。
我試過的:
"role"
和JwtClaimTypes.Role
之間切換。IdentityResources
關於ProfileService
的腳注
我試過添加這個:
public class ProfileService : TestUserProfileService
{
public ProfileService(TestUserStore users, ILogger<TestUserProfileService> logger)
: base(users, logger)
{ }
public override Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var role = context.Subject.FindFirst(ClaimTypes.Role);
context.IssuedClaims.Add(role);
return base.GetProfileDataAsync(context);
}
public override Task IsActiveAsync(IsActiveContext context)
{
return base.IsActiveAsync(context);
}
}
到AddIdentityServer()
構建器鏈:
.AddProfileService<ProfileService>()
但是GetProfileDataAsync(...)
方法根本沒有被命中,沒有斷點觸發。 所以這表明默認的TestUserProfileService
也永遠不會被擊中,從而解釋了我的令牌中缺少聲明。
密碼流是否不支持這可能是因為它是 OAuth2 而不是 OpenID Connect 流?
我錯過了什么? 我真的需要創建一個自定義ProfileService
來添加所有這些聲明嗎? 我真的覺得TestUser
的默認ProfileService
應該已經這樣做了?
我最終得到了以下結果(不確定它是解決方案還是解決方法),對於未來的訪問者來說是什么價值:
new ApiResource("foo-api")
{
Scopes =
{
new Scope("foo-api.with.roles", new[] { "role" }),
}
}
new Client
{
// Don't use RPO if you can prevent it. We use it here
// because it's the easiest way to demo with users.
ClientId = "legacy-rpo",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowAccessTokensViaBrowser = false,
RequireClientSecret = false,
AllowedScopes = { "foo-api", "foo-api.with.roles" },
}
new TestUser
{
SubjectId = "EFG-456",
Username = "mary",
Password = "secret",
Claims = { new Claim("role", "editor") },
}
然后像這樣檢索令牌:
const response = await fetch("/connect/token", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: new URLSearchParams({
"grant_type": "password",
"client_id": "legacy-rpo",
"username": "mary",
"password": "secret",
}),
});
const json = await response.json();
console.log(json);
您應該能夠克隆我的sample-asp-net-core-auth-policies
存儲庫並開箱即用地運行它以查看它的工作情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.