abp vnext框架重写volo.abp.openiddict的tokenController登录验证
在 ABP vNext 框架下,可以通过继承 TokenController
并重写 HandleAsync
方法来自定义 OpenIddict 的登录验证逻辑。以下是具体实现步骤:
1. 创建自定义 CustomTokenController
在主机Host项目的Controller文件夹下新建一个类继承自 TokenController
,并重写 HandleAsync
方法。例如,实现一个基于手机号和验证码的登录验证:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using OpenIddict.Server.AspNetCore;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp.OpenIddict.Controllers;
[Route("/connect/token")]
public class CustomTokenController : TokenController
{
public override async Task<IActionResult> HandleAsync()
{
var request = await GetOpenIddictServerRequestAsync(HttpContext);
// 自定义手机号和验证码登录逻辑
if (request.GrantType == "phone_verify")
{
var phoneNumber = request.GetParameter("phone_number");
var verificationCode = request.GetParameter("verification_code");
if (string.IsNullOrEmpty(phoneNumber) || string.IsNullOrEmpty(verificationCode))
{
return Forbid(new AuthenticationProperties(new Dictionary<string, string>
{
{ OpenIddictServerAspNetCoreConstants.Properties.Error, OpenIddictConstants.Errors.InvalidGrant },
{ OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription, "手机号或验证码不能为空" }
}));
}
// 验证手机号和验证码
var user = await ValidatePhoneNumberAndCodeAsync(phoneNumber, verificationCode);
if (user == null)
{
return Forbid(new AuthenticationProperties(new Dictionary<string, string>
{
{ OpenIddictServerAspNetCoreConstants.Properties.Error, OpenIddictConstants.Errors.InvalidGrant },
{ OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription, "手机号或验证码无效" }
}));
}
// 验证成功,生成令牌
var principal = await SignInManager.CreateUserPrincipalAsync(user);
return SignIn(principal, OpenIddictServerAspNetcoreDefaults.AuthenticationScheme);
}
// 调用基类方法处理其他 GrantType
return await base.HandleAsync();
}
private async Task<IdentityUser> ValidatePhoneNumberAndCodeAsync(string phoneNumber, string verificationCode)
{
// 实现手机号和验证码的验证逻辑
// 示例:从数据库中查找用户并验证验证码
// 这里需要根据实际业务逻辑实现
return await Task.FromResult(new IdentityUser()); // 示例返回值
}
}
2. 配置 OpenIddict 支持自定义 GrantType(可选)
在 OpenIddict 配置中,需要通过 OpenIddictServerBuilder
的 AllowCustomFlow
方法启用自定义的 GrantType:
注:该步骤根据实际情况选择,若无自定义的GrantType,可不配置。
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddOpenIddict()
.AddServer(options =>
{
options.AllowCustomFlow("phone_verify"); // 自定义 GrantType
});
}
3. 注册自定义 CustomTokenController
在模块配置中,需要注册自定义的 CustomTokenController
,以替换默认的 TokenController
:
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<CustomTokenController>();
}
4. 配置路由
确保自定义的 CustomTokenController
使用正确的路由。如果需要使用与默认 TokenController
相同的路由,可以通过配置路由优先级来实现。
[Route("/connect/token", Order = -1)]
public class CustomTokenController : TokenController
{
// 自定义逻辑
}
注意事项
-
自定义的 GrantType(如
phone_verify
)需要与客户端请求中的grant_type
一致。 -
在自定义逻辑中,可以根据实际需求实现手机号和验证码的验证逻辑。
-
如果需要支持其他 GrantType,可以在
HandleAsync
方法中添加相应的逻辑。