我们正在学习Identity Server,最终目标是将我们现有的身份验证服务迁移到它。出于公司、后勤和兼容性的原因,我们坚持使用IS 3。我们还没有完全准备好转移到Core。
我的问题有两部分:
1) 我修改了这里提供的示例应用程序,该应用程序使用自定义登录页面,以便浏览器提示用户输入X509Certificate2(作为部分登录)。用户输入密码,证书用于调用另一个端点,该端点返回用户特定的数据。此时,我们希望根据返回的数据创建自定义用户声明,然后发布cookie。
这一切都很好,直到客户端收到cookie我似乎无法提取添加到客户端应用程序上AuthenticatedLogin
的Claims
对象的自定义声明客户端配置为访问所有作用域。
我好像错过了一些基本的东西。我是不是做错了什么?请记住,这些只是用于测试目的的毫无意义的声明。
2) 这是一种可以接受的索赔方式吗?然后,我们可能会使用返回的cookie来调用单独的授权服务,因为我们的角色相当复杂。
我已经实现了自定义用户服务,PreAuthenticateAsync
重定向到自定义登录页面:
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
var id = ctx.Request.Query.Get("signin");
context.AuthenticateResult = new AuthenticateResult("~/custom/login?id=" + id, (IEnumerable<Claim>)null);
return Task.FromResult(0);
}
创建索赔并调用IssueLoginCookie
:的控制器方法
[RequireHttps]
[Route("core/custom/login")]
[HttpPost]
public ActionResult Index(string id, string password)
{
var userData = GetUser(password);
var owinEnvironment = Request.GetOwinContext().Environment;
var authenticatedLogin = new AuthenticatedLogin
{
IdentityProvider = Constants.BuiltInIdentityProvider,
Name = userData.UserName,
Subject = userData.EmailAddress,
Claims = GetClaims(userData),
PersistentLogin = false
};
owinEnvironment.IssueLoginCookie(authenticatedLogin);
var msg = owinEnvironment.GetSignInMessage(id);
var returnUrl = msg.ReturnUrl;
owinEnvironment.RemovePartialLoginCookie();
return Redirect(returnUrl);
}
// add our CUSTOM claims
private List<Claim> GetClaims(CustomUser authenticatedUser)
{
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("claim1", authenticatedUser.CustomClaim1));
claims.Add(new Claim("claim2", authenticatedUser.CustomClaim2));
claims.Add(new Claim("claim3", authenticatedUser.CustomClaim3));
claims.Add(new Claim("Claim4", authenticatedUser.CustomClaim4));
return claims;
}
带有Authorize
装饰器的客户端控制器方法:
[Authorize]
public ActionResult About()
{
// "CustomClaim1", "CustomClaim2" etc are not there :(
return View((User as ClaimsPrincipal).Claims);
}
在内存中注册的范围:
var scope1 = new Scope
{
Enabled = true,
Name = "user",
Type = ScopeType.Identity,
Claims = new List<ScopeClaim>
{
new ScopeClaim("CustomClaim1", true),
new ScopeClaim("CustomClaim2", true),
new ScopeClaim("CustomClaim3", true),
new ScopeClaim("CustomClaim4", true),
},
IncludeAllClaimsForUser = true
};
最后是客户端的Configuration
:
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost/idprov/core",
ClientId = "mvc",
RedirectUri = "https://localhost/dummyclient/About",
ResponseType = "id_token",
ClientSecret = "secret",
Scope = "openid partyuser",
SignInAsAuthenticationType = "Cookies",
});
}
嗨,试着像一样在客户端中添加作用域
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost/idprov/core",
ClientId = "mvc",
RedirectUri = "https://localhost/dummyclient/About",
ResponseType = "id_token",
ClientSecret = "secret",
Scope = "openid partyuser CustomClaim1 CustomClaim2",
SignInAsAuthenticationType = "Cookies",
});