我根据GitHub上的UI示例项目说明设置了基本的Identity Server。我已将其设置为使用我们的现场AD进行Windows身份验证。这很漂亮。
我的问题是将用户AD组添加到声明中。根据示例项目,我启用了IncludeWindowsGroups
选项。这似乎是将声明添加到ClaimsIdentity。但是,在我的MVC客户端上,当我打印出声明时,我只会得到相同的结果4.它们是sid
,sub
,idp
和name
。我已经尝试添加其他声明,但我永远不会让任何其他人出现。
我有以下作为我的客户端设置:
return new List<Client>
{
// other clients omitted...
// OpenID Connect implicit flow client (MVC)
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" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
RequireConsent = false
}
};
希望我只是缺少一些简单的东西,但我现在正在努力寻找想法,所以任何指针都会非常感激。
答案 0 :(得分:2)
除了在IdentityServer4项目中设置IncludeWindowsGroups = true
之外,我还设法进行了一些更改。请注意,我从2.2.0 tag
在GitHub中,每个this comment都在快速入门用户界面中修改了ExternalController.cs:
// this allows us to collect any additonal claims or properties
// for the specific prtotocols used and store them in the local auth cookie.
// this is typically used to store data needed for signout from those protocols.
var additionalLocalClaims = new List<Claim>();
var roleClaims = claims.Where(c => c.Type == JwtClaimTypes.Role).ToList();
if (roleClaims.Count > 0)
{
additionalLocalClaims.AddRange(roleClaims);
}
然后我创建了一个配置文件服务,将Windows Auth中的声明复制到要发送回的令牌中:
public class ProfileService : IProfileService
{
private readonly string[] _claimTypesToMap = {"name", "role"};
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
foreach (var claimType in _claimTypesToMap)
{
var claims = context.Subject.Claims.Where(c => c.Type == claimType);
context.IssuedClaims.AddRange(claims);
}
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true; //use some sort of actual validation here!
return Task.CompletedTask;
}
}
并在Startup.cs中向IdentityServer4注册
services
.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(StaticConfig.GetIdentityResources())
.AddInMemoryApiResources(StaticConfig.GetApiResources())
.AddInMemoryClients(StaticConfig.GetClients())
.AddTestUsers(StaticConfig.GetUsers())
.AddProfileService<ProfileService>();
在IdentityServer4的客户端配置中,我将用户声明设置为包含在ID令牌中。我发现,如果我尝试将回调中的声明映射到UserInfo,该上下文将在IdentityServer4中丢失,因此声明将不会映射。
public static class StaticConfig
{
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
...
AlwaysIncludeUserClaimsInIdToken = true,
...
}
}
}
}
最后,在客户端网站的Startup.cs
中,我不设置了UserInfo回调;我只是确保映射了我的姓名和角色声明。请注意,如果您的个人资料服务返回了任何其他声明类型,则需要通过调用options.ClaimActions
上的辅助方法来手动映射它们。
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.ClientSecret = "secret";
options.SaveTokens = true;
options.ResponseType = "code id_token";
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
//map any other app-specific claims we're getting from IdentityServer
options.ClaimActions.MapUniqueJsonKey("someotherclaimname", "someotherclaimname");
};