【问题标题】:Programatically create an OpenID Connect id_token with IdentityServer3使用 IdentityServer3 以编程方式创建 OpenID Connect id_token
【发布时间】:2017-07-11 03:30:06
【问题描述】:

我将 IdentityServer3 添加到现有网站(具体为 NopCommerce)。它有自己的注册和认证系统,但我们还需要提供 OpenID Connect 以便可以集成后端应用程序。对后端的调用需要有当前用户的 id_token 由后端验证以确认身份。

我找到了有关如何使用现有成员数据库为 IdentityServer3 提供用户数据以检查的信息,但是我对如何为每个用户生成 id_token 有点困惑。我想显而易见的答案是用 IdentityServer 替换网站登录,但这会给项目的其余部分带来更多问题。理想情况下,我希望用户正常登录,然后调用 IdentityServer 中的方法来生成 id_token。

这可能吗?我一直在四处寻找,但到目前为止找不到任何东西。我找到的最好的答案是programmatically sign in to identityserver3。我认为它建议向 IdentityServer 发布 HTTP 帖子,但感觉有点 hacky。

我还找到了Implementing OAuth 2.0 and OpenId Connect provider using IdentityServer3 with existing login server and membership provider,但我不得不承认,这是假设我(还)不具备相当多的知识。

【问题讨论】:

  • 我试过programmatically sign in to identityserver3的代码,发现这总是返回一个access_token,不幸的是后端必须有id_token。
  • 看到这个类:github.com/IdentityServer/IdentityServer3/blob/master/source/… - 如果你可以实例化它,你可能可以用它生成一个 id_token
  • 感谢您找到我认为关键部分在“如果我可以实例化它”的类。到目前为止,我已经按照 JohnC 在他的回答中建议的那样实现了一个简单的 IdentityServer,并且正在探索它是否适合我们的要求。

标签: identityserver3


【解决方案1】:

我基于 John C 的回答的解决方案使用 NopCommece 外部身份验证插件工作,但我对在 IdentityServer 使用 Nop 数据库时不得不离开 Nop 进行身份验证和注册感到不满。通过外部身份验证路由似乎是获得 OpenID Connect id_token 的唯一方法。休息一段时间后,我发现了以下代码:

https://identityserver.github.io/Documentation/docsv2/configuration/serviceFactory.html https://identityserver.github.io/Documentation/docsv2/configuration/serviceFactory.html

通过实现自定义服务,IdentityServer 允许您搞乱令牌的创建和生成,并且它使用的依赖注入系统使您可以访问默认服务的实例化版本。

以前我遵循一个将用户名和密码发送到令牌端点的答案。 OpenID 规范说这应该只返回 access_token,这正是 IdenttyService 中的 DefaultTokenService 所做的。但是,通过添加 CustomTokenResponseGenerator,我也能够重新使用请求来创建和返回 id_token。

CustomTokenResponse 类:

internal class CustomTokenResponseGenerator : ICustomTokenResponseGenerator
{

    protected ITokenService _tokenService;

    public CustomTokenResponseGenerator(ITokenService tokenService)
    {
        _tokenService = tokenService;
    }

    public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
    {
        var tokenRequest = new TokenCreationRequest
        {
            Subject = request.Subject,
            Client = request.Client,
            Scopes = request.ValidatedScopes.GrantedScopes,
            //Nonce = request.AuthorizationCode.Nonce,

            ValidatedRequest = request
        };
        var idToken = _tokenService.CreateIdentityTokenAsync(tokenRequest);
        idToken.Wait();
        var jwt = _tokenService.CreateSecurityTokenAsync(idToken.Result);
        response.IdentityToken = jwt.Result;
        return Task.FromResult(response);
    }
}

如何在 Startup.cs 中注入自定义服务:

 factory.TokenService = new Registration<ITokenService, TokenService>();
 factory.CustomTokenResponseGenerator = new Registration<ICustomTokenResponseGenerator, CustomTokenResponseGenerator>();

【讨论】:

  • 在您的代码中看起来您正在调用异步方法,而没有在其前面使用 await 关键字。如果该方法确实是异步方法,则需要在方法 GenerateAsync 之前添加 async 关键字,然后在调用 CreateIdentityTokenAsync 和 CreateSecurityTokenAsync 时使用 await 关键字。然后只返回响应本身,没有 FromResult。
  • @Suddy 你在这里注册一个 TokenService,它是什么? IS3 除了 DefaultTokenService 之外没有其他任何东西,您是否创建了自定义服务?
  • 想通了,只需更改为 DefaultTokenService 就可以了:factory.TokenService = new Registration&lt;ITokenService, DefaultTokenService&gt;();
【解决方案2】:

当用户登录到 NopCommerce 应用程序时,您可以向身份服务器发送 HTTP 授权请求。确保在向 idsrv 发送授权请求时使用 prompt=none,这样如果用户已经登录,您将获得 id_token 或 access_token 而无需再次向用户表示同意。

    function getAuthorizeRequest() {
var url = global.appSettings.identityServerURL
                    + "/connect/authorize?client_id=siteB&response_type=id_token token&redirect_uri="
                    + global.appSettings.siteBUrl + "/Main/NopCommerceapp&scope=siteBscope openid email roles&prompt=none&nonce="76767xz676xzc76xz7c67x6c76"                       
return encodeURI(url);}

结帐 idsrv 授权端点 https://identityserver.github.io/Documentation/docsv2/endpoints/authorization.html

【讨论】:

  • 谢谢,但我不太确定我是否遵循。文档说“在请求期间不会显示任何 UI。如果这是不可能的(例如,因为用户必须登录或同意),则会返回错误”。我的用户已登录 NopCommerce,但未登录 IdentityServer,因此他们只是收到错误响应。
【解决方案3】:

我认为您最好的解决方案是实施 IdentityServer3 并从您现有的 Nop 成员数据库中读取它。然后创建一个使用您的 IdentityServer3 设置自行运行的 Web API 应用程序。在 Web API 中,您实现了后端应用所需的所有功能,读取和写入 Nop 数据库。

将您的 Nop 前端 UI 与后端 API 分开。如果您点击下面的两个链接,您应该能够很快地启动并运行一些东西。

Creating the simplest OAuth2 Authorization Server, Client and API
MVC Authentication & Web APIs

【讨论】:

猜你喜欢
  • 2018-01-15
  • 2018-04-25
  • 2013-10-18
  • 1970-01-01
  • 2017-05-18
  • 2020-05-09
  • 2019-10-15
  • 2015-05-21
  • 2019-09-28
相关资源
最近更新 更多