使用 IdentityServer3 以编程方式创建 OpenID Connect id_token

Programatically create an OpenID Connect id_token with IdentityServer3

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

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

这可能吗?我一直在四处寻找,但到目前为止找不到任何东西。我找到的最好的答案是 。我认为它建议为 IdentityServer 创建一个 HTTP post,但感觉有点老套。

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

当用户登录到 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

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

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

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

我基于 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 规范说这应该只 return access_token,这正是 IdenttyService 中的 DefaultTokenService 所做的。但是,通过添加 CustomTokenResponseGenerator,我能够重新使用请求来创建 return 和 id_token。

CustomTokenResponse class:

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>();