【问题标题】:Dynamically adding steps to SSO with IdentityServer4使用 IdentityServer4 向 SSO 动态添加步骤
【发布时间】:2018-12-24 15:04:02
【问题描述】:

在尝试从 identityServer4 QuickStart 9 自定义快速入门之一时,我遇到了一些问题,基本上,我需要创建一个单点登录应用程序,该应用程序将被多个服务、多个 Web 应用程序、一个电子、和 PhoneGap 应用程序。

目前,我的流程比简单地对用户进行身份验证要复杂一些,见下文:

用户输入登录名和密码 -> 系统验证这条数据并向用户提供可供选择的可能子应用程序的选择 -> 用户选择其中一个子应用程序 -> 系统现在请求用户为这个应用程序选择一个可能的环境(可以自定义暂存/生产)

我想在身份验证层上执行此流程,否则我将不得不在所有应用程序上复制所有这些步骤,而且我当然希望身份验证具有单独的开发生命周期。

目前,我正在尝试进行 3 处修改以实现此目的:

  1. PersistentGrantStore -> 使用 授予密钥作为参考。 (就像是 密钥/应用程序/环境)

  2. IProfileService -> 添加代表此步骤的自定义声明 (卡在这里),并且是临时的,它们只对这个令牌和后续刷新有意义。

  3. authenticationHandler -> 验证用户是否通过了所有 步骤

由于我的 spa 的应用程序,我还需要修改令牌端点以通过自定义标头接受这 2 个参数

我的问题归结为:有更好的方法吗?我是否过于复杂了?

对不起,如果这个问题太基本了,但我不习惯做这种类型的身份验证。

【问题讨论】:

  • 不太确定我是否理解您的问题,但是关于应用程序和环境的所有内容都不是必需的。您的每个应用程序都在您的身份服务器中获得它自己的 客户端条目。即 App A Production 和 App A Staging、App B Production、App B staging。这些您在身份中配置,告诉它哪些声明添加/返回到必要的端点/令牌类型。
  • 对我来说,这听起来像是您正在尝试使用相同的客户端 ID 运行多个应用程序。这不是 OpenID 意义上的。对于 OpenID,每个应用程序和环境都应该有一个客户端条目,这种唤醒撤销可以更详细地工作(阻止特定客户端)并且它也是为了安全。客户端 ID 和客户端密码是机密的(服务器应用程序),您可以为不同的应用程序使用不同的流程(服务器的身份验证代码,移动应用程序和浏览器应用程序的隐式等)
  • 实际上,我并没有考虑为所有应用程序使用相同的 clientId,我所说的“具有多个客户端的多个应用程序”的意思是每个应用程序都是一个多租户应用程序,每个租户都可以连接到多个环境(数据库) - 基本上令牌 A 是为具有环境 C 的应用程序 B 生成的,这些应该单独成为这个令牌的声明。

标签: asp.net asp.net-core single-sign-on single-page-application identityserver4


【解决方案1】:

如果我理解正确,以下方法可能会有所帮助。

创建一个临时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);
            })

如果您想使用外部登录,请适当更改上述代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    相关资源
    最近更新 更多