我已经建立了以下三个资产的解决方案:
当前,身份验证有效:如果我尝试访问MVC应用程序中的受保护资源,它将重定向到IdentityServer4,那么我可以使用我的Facebook帐户登录,配置用户并生成主题ID,然后我m重定向回MVC应用。这可以正常工作。
我还可以从MVC站点内调用受保护的Web API函数。但是,在我从Web API中收到的声明中,我没有收到主题ID。
如果我进一步调查,那么我可以在MVC应用程序中看到,我从RequestClientCredentialsTokenAsync调用中获取了访问令牌,但它仅包含:
{
"nbf": 1548693531,
"exp": 1548697131,
"iss": "http://localhost:5000",
"aud": [
"http://localhost:5000/resources",
"mgpApi"
],
"client_id": "mgpPortal",
"scope": [
"mgpApi"
]
}
我想要的是,我也收到此访问令牌中的主题ID ,这样我也可以在调用的Web API函数中使用它。
我的IdentityServer4主机配置有:
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Resources.GetIdentityResources())
.AddInMemoryApiResources(Resources.GetApiResources())
.AddProfileService<ProfileService>()
.AddInMemoryClients(Clients.Get());
}
...并且我正在使用以下方式注册客户端:
new Client
{
EnableLocalLogin = false,
ClientId = "mgpPortal",
ClientName = "MGP Portal Site",
AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,
// 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" },
// secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"mgpApi"
},
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true,
AlwaysSendClientClaims = true,
}
...而且我也尝试通过ProfileService这样的声明来添加声明,例如:
public class ProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.IssuedClaims.AddRange(context.Subject.Claims);
context.IssuedClaims.Add(new Claim("sub", "test"));
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.FromResult(0);
}
}
但这没什么区别。
我的MVC客户端配置有:
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mgpPortal";
options.SaveTokens = true;
});
}
那么我应该添加些什么以便在访问令牌中接收主题ID?
如果需要更多信息,请告诉我。任何帮助表示赞赏!
答案 0 :(得分:2)
您使用了错误的流程,请使用hybrid
流程。在client credentials
中,没有用户主题的概念,因此您遇到的问题。
答案 1 :(得分:0)
我处于类似情况。经过大量的证明,我发现使用MVC应用程序用户的相同令牌访问另一个Web Api应用程序非常容易。说明here:
public async Task<IActionResult> CallApi()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
...
}
使用IdentityModel的另一个版本:
public async Task<IActionResult> CallApi()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var apiClient = new HttpClient();
client.SetBearerToken(accessToken);
....
await client.PutAsync(url, json);
希望它可以帮助...