1

我已经实现了 OpenID Connect 服务器,它使用OpenIddict根据用户名/密码为移动客户端生成访问令牌。我的下一个目标是提供使用 3-rd 方令牌(例如社交登录)生成访问令牌的能力,我从与 Google 令牌集成开始,但由于找不到任何有关如何执行此操作的示例/信息而陷入困境。

我目前唯一的想法是向“/connect/token”端点发出请求并以“code”参数发送谷歌令牌,例如以“google:”格式,然后覆盖OpenIdConnectServerProvider.DeserializeAuthorizationCode方法:

收到授权码时调用。应用程序可以使用此上下文使用自定义格式反序列化代码,并使用以下方式跳过默认逻辑

所以我创建了自己的CustomProviderOpenIddictProvider,注册它

services.AddOpenIddict<ApplicationUser, ApplicationRole, ApplicationDbContext, int>()
    .Configure(builder =>
    { builder.Provider = new CustomProvider(sp.GetRequiredService<SignInService>()); }

并覆盖该DeserializeAuthorizationCode方法:

public override async Task DeserializeAuthorizationCode(DeserializeAuthorizationCodeContext context)
{
    string code = context.Request.Code;
    if (code.StartsWith("google:"))
    {
        string token = code.Replace("google:", "");
        var principal = new GoogleTokenValidator().ValidateToken(token, null).Result;
        var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), "Bearer");
        ticket.SetPresenters(context.Request.ClientId);
        context.Ticket = ticket;

        context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(1);
        context.HandleResponse();

        await _signInService.Login(principal);

        return; 
    }
    else
    {
        base.DeserializeAuthorizationCode(context);
    }
} 

whereGoogleTokenValidator是用于 Google 令牌处理的自定义类(它调用 Google 用户信息端点并生成 ClaimsPrincipal),基于aspnet/Security repo 中GoogleHandler类的“复制粘贴”代码。

总的来说,它正在使用一些额外的技巧,但我有强烈的感觉,重新发明轮子......

4

1 回答 1

1

总的来说,它正在使用一些额外的技巧,但我有强烈的感觉,重新发明轮子......

您不仅在重新发明轮子,而且还实现了 OpenIddict(根本)不支持的完全非标准的东西。

这是我推荐的方法(这是我们在 MVC 服务器示例中使用的方法):

  • OAuth2/OpenID Connect 客户端应用程序将用户代理重定向到您的授权控制器(您可以查看此控制器作为示例)。

  • OpenIddict 将验证授权请求,如果它完全有效,则允许调用您的控制器。

  • 如果用户尚未登录,您的授权控制器会将用户重定向到登录端点,由AccountController. 此时,您可以自由地提出本地身份验证(例如使用用户名/密码对)或 Google 身份验证(您可以为此使用 Google 身份验证中间件)。您甚至可以在此登录过程中提供 2-FA。

  • 一旦用户登录(例如在注册过程和/或外部身份验证关联之后),他/她的浏览器将被重定向回授权端点,其中表示他/她将允许您的 JS 应用程序访问他的同意表单显示代表他/她的个人数据。

  • 当用户允许您的客户端应用程序访问他的数据时,请求由您的授权控制器处理,该调用SignInAsync通知 OpenIddict 应将授权代码/访问令牌返回给您的应用程序。

于 2016-07-15T14:10:44.837 回答