diff --git a/src/SecurityTokenService/Controllers/AccountController.cs b/src/SecurityTokenService/Controllers/AccountController.cs index 333e039..384f504 100644 --- a/src/SecurityTokenService/Controllers/AccountController.cs +++ b/src/SecurityTokenService/Controllers/AccountController.cs @@ -45,6 +45,9 @@ public class AccountController( private readonly SecurityTokenServiceOptions _options = options.CurrentValue; private readonly IdentityExtensionOptions _identityExtensionOptions = identityExtensionOptions.CurrentValue; + private static readonly bool PasswordLoginTwoFactorEnable = + bool.Parse(Environment.GetEnvironmentVariable("STS_PASSWORD_LOGIN_TWOFACTOR") ?? "false"); + /// /// 通过旧密码修改密码 /// 要提供用户名 @@ -190,10 +193,13 @@ public async Task Login([FromBody] Inputs.V1.LoginInput model) return new ObjectResult(new RedirectResult("/")); } - var checkCaptchaResult = Util.CheckCaptcha(memoryCache, logger, Request, model.CaptchaCode); - if (checkCaptchaResult != null) + if (!PasswordLoginTwoFactorEnable) { - return new ObjectResult(checkCaptchaResult); + var checkCaptchaResult = Util.CheckCaptcha(memoryCache, logger, Request, model.CaptchaCode); + if (checkCaptchaResult != null) + { + return new ObjectResult(checkCaptchaResult); + } } var user = await userManager.FindAsync(model.Username, _identityExtensionOptions.SoftDeleteColumn); @@ -208,6 +214,20 @@ await events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid crede }); } + if (PasswordLoginTwoFactorEnable) + { + var isValid = await userManager.VerifyUserTokenAsync(user, Util.PhoneNumberTokenProvider, + Util.PurposeLogin, + model.VerifyCode); + if (!isValid) + { + return new ObjectResult(new ApiResult + { + Code = Errors.VerifyCodeIsInCorrect, Success = false, Message = "手机验证码不正确" + }); + } + } + var result = await signInManager.PasswordSignInAsync(user, model.Password, model.RememberLogin, true); if (result.Succeeded) @@ -215,6 +235,7 @@ await events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid crede await events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId)); + if (context != null) { // if (await _clientStore.IsPkceClientAsync(context.Client.ClientId)) diff --git a/src/SecurityTokenService/Controllers/Inputs.cs b/src/SecurityTokenService/Controllers/Inputs.cs index 6c479fb..b8f2b0a 100644 --- a/src/SecurityTokenService/Controllers/Inputs.cs +++ b/src/SecurityTokenService/Controllers/Inputs.cs @@ -199,6 +199,12 @@ public class LoginInput /// [StringLength(10, ErrorMessage = "验证码长度超长"), Required(ErrorMessage = "请输入验证码")] public string CaptchaCode { get; set; } + + /// + /// 验证码 + /// + [StringLength(8, ErrorMessage = "验证码长度不正确")] + public string VerifyCode { get; set; } } public class LogoutInput