asp.net - 使用 IdentityServer4 向 SSO 动态添加步骤
问题描述
在尝试从 identityServer4 QuickStart 9自定义快速入门之一时,我遇到了一些问题,基本上,我需要创建一个单点登录应用程序,该应用程序将被多个服务、多个 Web 应用程序、一个电子和 PhoneGap 应用程序使用。
目前,我的流程比简单地验证用户要复杂一些,见下文:
用户输入登录名和密码 -> 系统验证这条数据并向用户提供可供选择的可能子应用程序的选择 -> 用户选择其中一个子应用程序 -> 系统现在要求用户选择一个可能的子应用程序此应用程序的环境(可以自定义暂存/生产)
我想在身份验证层上执行此流程,否则,我将不得不在所有应用程序上复制所有这些步骤,而且我当然希望身份验证具有单独的开发生命周期。
目前,我正在尝试进行 3 处修改以实现此目的:
PersistentGrantStore -> 使用授权键作为参考将此步骤保存到自定义表中。(类似于密钥/应用程序/环境)
IProfileService -> 添加代表此步骤的自定义声明 (卡在此处),并且是临时的,它们仅对此令牌和后续刷新有意义。
authenticationHandler -> 验证用户是否完成了所有步骤
由于我的水疗中心的应用程序,我还需要对令牌端点进行修改以通过自定义标头接受这两个参数
我的问题归结为:有更好的方法吗?我是否过于复杂了?
对不起,如果这个问题太基本了,但我不习惯做这种类型的身份验证。
解决方案
如果我理解正确,以下方式可能会有所帮助。
创建一个临时 cookie 并在用户登录后显示选择页面:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model, string button)
{
if (ModelState.IsValid)
{
var loginResult = .service.Check(model.Username, model.Password);
if (loginResult.IsSucceed)
{
await HttpContext.SignInAsync("TempCookies", loginResult.Principal);
var selectViewModel = new SelectViewModel();
model.ReturnUrl = model.ReturnUrl;
return View("SelectUserAndEnvironment", selectViewModel);
}
else
{
ModelState.AddModelError("", "****.");
return View(model);
}
}
return View(model);
}
添加您想要的声明并登录IdentityServerConstants.DefaultCookieAuthenticationScheme
[HttpPost]
[Authorize(AuthenticationSchemes = "TempCookies")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SelectUserAndEnvironment(SelectModel model)
{
// add claims from select input
var claims = new List<Claim>();
claims.Add(new Claim(<Type>, <Value>));
var p = new ClaimsPrincipal(new ClaimsIdentity(auth.Principal?.Identity, claims));
await HttpContext.SignOutAsync("TempCookies");
await HttpContext.SignInAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme, p);
return Redirect(model.ReturnUrl);
}
并在ProfileService
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
// you can get claims added in login action by using context.Subject.Claims
// other stuff
context.IssuedClaims = claims;
await Task.CompletedTask;
}
最后在中添加身份验证方案Startup.cs
services.AddAuthentication()
.AddCookie("TempCookies", options =>
{
options.ExpireTimeSpan = new TimeSpan(0, 0, 300);
})
如果要使用外部登录,请适当更改上述代码。
推荐阅读
- python - 使用 Python 转换 DataFrame
- aws-amplify - AWS Amplify 发布到自定义域
- google-apps-script - Google Sheets 脚本可在多页文档中打开最后修改的表单
- php - 如何更改 laravel 框架上的搜索地址?
- python - 如何使用 Python 测试是否在函数内部调用了实例方法?
- css - 为单选按钮添加无效的类 CSS
- c# - 已发布的 .NET 框架 3.5 程序在安装期间需要 .NET 框架 4.7.2
- javascript - jQuery for 循环仅获取第一项值
- c - 如何创建具有动态行和列大小的动态字符数组
- laravel-5.8 - 在 checkAdmin 和 CheckUser 中间件条件为真后,Laravel 页面无法正常工作