我已经阅读了类似的问题,但我没有找到我的用例 . 我们有一个使用AspNetIdentity Forms Authentication的旧MVC应用程序 . 我们开始将站点的一部分转换为使用IdentityServer3 IdP的新系统 . 从用户的角度来看,他们会登录“旧”网站 . 进一步进入网站后,他们可能会被重定向到新网站 . 目前,当发生这种情况时,他们必须再次登录到SSO页面以获取新的SSO cookie . 我们正在努力减轻双重意义 .
在后端,用户的帐户在两个身份验证数据库之间同步,因此其用户名和密码始终保持同步 . 为了减少双重登录,我试图在“旧”站点的登录页面上使用资源所有者流,因此它首先执行Forms Auth登录,然后使用资源所有者将凭据传递给IdentityServer以便使用新系统进行身份验证 . 我想,如果SSO服务器auth在此时发生,可以构建一个cookie,以便稍后当他们导航到受SSO保护的站点时,他们已经拥有一个有效的cookie . 我发现的问题是资源所有者方法似乎没有发出cookie . 我在IdentityServer托管网站上创建了一个MVC控制器,用于执行资源所有者身份验证 . 我有“旧”站点为此页面打开一个新的浏览器选项卡,以便在发出Set-Cookie时HttpGet控制器响应将返回到浏览器 . 资源所有者auth工作,我得到一个访问令牌,userInfo get也可以工作 . 我使用OWIN身份验证管理器构建ClaimsIdentity和SignIn . 声明主体显示用户已通过身份验证,但我没有收到cookie . 有没有办法实现这一目标 .
总之,在“旧”系统登录时使用他们的明文凭据我想用SSO预先验证它们以获取cookie,因此稍后导航到SSO站点不会要求登录 .
这是资源所有者Auth Get控制器 .
public ActionResult LoginGet(string username, string password) {
try {
username = HttpUtility.UrlDecode(username);
password = HttpUtility.UrlDecode(password);
//create identityserver sso cookie as well
var tokenClient = new TokenClient(
"https://localhost.fiddler:44333/core/connect/token",
"clientId",
"secret"
);
var scopes = "openid profile sampleApi roles";
var token = tokenClient.RequestResourceOwnerPasswordAsync(username, password, scopes).Result;
if (token != null && !String.IsNullOrWhiteSpace(token.AccessToken)) {
var claims = new List<Claim>();
var claimsClient = new UserInfoClient(new Uri("https://localhost.fiddler:44333/core/connect/userinfo"), token.AccessToken);
var userInfo = claimsClient.GetAsync().Result;
userInfo.Claims.ToList().ForEach(t => claims.Add(new Claim(t.Item1, t.Item2)));
claims.Add(new Claim("token", token.AccessToken));
var claimsId = new ClaimsIdentity(claims, "Cookies");
Request.GetOwinContext().Authentication.SignIn(claimsId);
ViewBag.Worked = true;
ClaimsPrincipal cp = Request.GetOwinContext().Authentication.User;
if(cp != null) {
ViewBag.IsAuthed = cp.Identity.IsAuthenticated;
}
return View();
}
} catch (Exception ex) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return View();
}
2 回答
在API /反向信道调用中对令牌 endpoints 的调用 . 要设置SSO cookie,必须将浏览器重定向到IdentityServer .
IOW - 如果没有浏览器重定向,您无法实现的目标 .
你可以't access or set cookies for a path(IdentityServer here) from another path even within the same host name (there sure are tricky ways to do that but of course, you'd知道要设置什么,等等 . 见https://security.stackexchange.com/q/12439
实现此目的的一种非常简单的方法是使用授权 endpoints ,该 endpoints 允许将其他身份验证相关信息传递给用户服务 . https://identityserver.github.io/Documentation/docsv2/endpoints/authorization.html . 然后,登陆IdentityServer 's sign in page, you can retrieve the user'的身份 .
为了简单起见:
在"old"系统中,加密用户的详细信息或提供某种形式的唯一哈希
重定向到IdentityServer或OWIN中间件时,在授权 endpoints 参数中包含哈希
在自定义UserService中获取此添加的参数(哈希),并从哈希中检索用户详细信息
在您的自定义UserService中,填充登录字段以提供用户友好的消息以继续,或者创建自定义ViewService动态提交表单
或自定义LoginPage . 检查here样品