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