我已经实现了OpenID Connect服务器,该服务器使用OpenIddict基于用户名/密码为移动客户端生成访问令牌。 我的下一个目标是提供使用第三方令牌(例如社交登录)生成访问令牌的能力,并且我从与Google令牌的集成开始,但因为无法找到有关如何执行此操作的任何示例/信息而停滞不前。
我目前唯一的想法是向“/ connect / token”端点发出请求并在“code”参数中发送Google令牌,例如以“google:”格式,然后覆盖OpenIdConnectServerProvider.DeserializeAuthorizationCode方法:
收到授权码时被叫。应用程序可以使用此上下文使用自定义格式反序列化代码,并使用
跳过默认逻辑
所以我基于CustomProvider
创建了自己的OpenIddictProvider
类,注册了它
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);
}
}
其中GoogleTokenValidator
是用于Google令牌处理的自定义类(它调用Google用户信息端点并生成ClaimsPrincipal),基于来自aspnet / Security中GoogleHandler类的“复制粘贴”代码回购。
总的来说,它正在使用一些额外的黑客,但我有强烈的感觉,重新发明轮子......
答案 0 :(得分:1)
总的来说,它正在使用一些额外的黑客,但我有强烈的感觉,重新发明轮子......
你不仅要重新发明轮子,而且还要实现OpenIddict不支持(根本不支持)的完全非标准的东西。
这是我推荐的方法(我们在MVC服务器示例中使用的方法):
OAuth2 / OpenID Connect客户端应用程序将用户代理重定向到您的授权控制器(您可以查看this controller示例)。
OpenIddict将验证授权请求,并允许控制器在完全有效的情况下被调用。
如果用户尚未登录,则授权控制器会将用户重定向到AccountController
提供的登录端点。此时,您可以自由地建议本地身份验证(例如使用用户名/密码对)或Google身份验证(您可以使用Google身份验证中间件)。您甚至可以在此登录过程中提供2-FA。
一旦用户登录(例如,在注册过程和/或外部认证关联之后),他/她的浏览器将被重定向回授权端点,其中的同意书表明他/她将要允许您的JS应用程序将代表他/她访问其个人数据。
当用户允许您的客户端应用程序访问其数据时,请求由授权控制器处理,该控制器调用SignInAsync
以通知OpenIddict应将授权代码/访问令牌返回给您的应用程序