我想使用 TOTP 软令牌将多因素身份验证添加到 Angular 和 Spring 应用程序,同时使所有内容尽可能接近Spring Boot Security Starter的默认值。
令牌验证发生在本地(使用 aerogear-otp-java 库),没有第三方 API 提供者。
为用户设置令牌有效,但通过利用 Spring Security Authentication Manager/Providers 验证它们无效。
API 有一个端点/auth/token,前端可以通过提供用户名和密码从中获取 JWT 令牌。响应还包括身份验证状态,可以是AUTHENTICATED或PRE_AUTHENTICATED_MFA_REQUIRED。
如果用户需要 MFA,则颁发令牌的单个授予权限PRE_AUTHENTICATED_MFA_REQUIRED为 5 分钟,到期时间为 5 分钟。这允许用户访问端点/auth/mfa-token,在那里他们可以从他们的 Authenticator 应用程序提供 TOTP 代码,并获得完全验证的令牌以访问站点。
我已经创建了我的自定义MfaAuthenticationProvider实现AuthenticationProvider:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// validate the OTP code
}
@Override …Run Code Online (Sandbox Code Playgroud) authentication spring-security spring-boot totp multi-factor-authentication
我正在使用Otp.NET库来生成和验证 OTP。我想使用TOTP算法。生成的 OTP 有效期需为 5 分钟。图书馆建议var totp = new Totp(secretKey, step: 300);为此使用。但是OTP在5分钟之前就失效了
完整代码
public static void GenarateTOTP()
{
var bytes = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP");
var totp = new Totp(bytes, step: 300);
var result = totp.ComputeTotp(DateTime.UtcNow);
Console.WriteLine(result);
var input = Console.ReadLine();
long timeStepMatched;
bool verify = totp.VerifyTotp(input, out timeStepMatched, window: null);
Console.WriteLine("{0}-:{1}", "timeStepMatched",timeStepMatched);
Console.WriteLine("{0}-:{1}", "Remaining seconds", totp.RemainingSeconds());
Console.WriteLine("{0}-:{1}", "verify", verify);
}
Run Code Online (Sandbox Code Playgroud) 在 Google Authenticator 应用中,您可以扫描二维码或手动输入颁发者提供的密钥。
在下面的屏幕截图中,您可以看到Google安全设置中2FA的设置,显示了如何按照第二种方法获取TOTP。
我的问题是:这个密钥是如何生成的?
我正在尝试为我的网站使用 Google Authenticator 支持 2FA,我发现了许多有关如何生成 QR 码的参考资料和文档,但没有提到替代方法。
编辑:
更清楚地说,我在 Grails 3 Web 应用程序中使用 Google Authenticator 支持 2FA。我已经通过为每个用户生成一个密钥(Base32字符串)、提供一个二维码供用户扫描以及在登录时验证 TOTP 来实现整个用户流程。我用作依赖项:
org.jboss.aerogear:aerogear-otp-java, aerogear OTP可根据 GA 的 TOTP 方便地验证用户密钥org.grails.plugins:qrcode, qrcode Grails 插件生成二维码我的问题是关于在 Google Authenticator 应用程序中添加新条目的 2 种方法: 1. 扫描二维码(我这边一切正常) 2. 手动输入帐户名称和字母代码(在我的第一个屏幕截图中,代码是在 Google 安全设置中提供)
您可以看到 Android 版 GA 的说明性屏幕截图:
我如何生成并向fzee用户提供这样的代码(从第一个屏幕截图开始,并在第二个屏幕截图中命名为“提供的密钥”)?我确信它是在 QR 码中编码的相同数据字符串的编码,但我不知道是哪个(不仅仅是Base32)。
qr-code one-time-password google-authenticator two-factor-authentication totp
我正在使用 AWS CLI 启用仅具有 TOTP MFA(无 SMS)的 MFA 用户池。
aws cognito-idp set-user-pool-mfa-config --user-pool-id xxxx_xxxx --mfa-configuration 可选 --software-token-mfa-configuration Enabled=true
{
"SoftwareTokenMfaConfiguration": {
"Enabled": true
},
"MfaConfiguration": "OPTIONAL"
}
Run Code Online (Sandbox Code Playgroud)
看起来还行吧?但是当我尝试设置用户首选项时,我不断收到此错误:
调用 AdminSetUserMFAPreference 操作时发生错误 (InvalidParameterException):用户尚未设置软件令牌 mfa
命令: aws cognito-idp admin-set-user-mfa-preference --user-pool-id xxxx_xxxx --username username@email.com --software-token-mfa-settings Enabled=true
尝试使用 admin-set-user-preference 也不起作用: aws cognito-idp admin-set-user-settings --user-pool-id us-xxxx-xxxx--username username@email.com --mfa -option DeliveryMedium=EMAIL
调用 AdminSetUserSettings 操作时发生错误 (InvalidParameterException):当前仅支持 phone_number 属性作为 MFA 选项。
我错过了什么?它是否需要文档中未提及的额外配置?
首先,您需要为用户获取 ACCESS_TOKEN 并继续启动 TOTP 过程:
aws cognito-idp associate-software-token --access-token ACCESS_TOKEN
(这将生成一个您可以在 Google Authenticator 中使用的唯一代码)
使用从 …
我们的网站可以从桌面和移动设备打开。当用户在桌面上设置 MFA 时,他们可以使用手机摄像头直接从 PC 屏幕扫描 QR 码。但是,当他们登录移动设备时,他们很难在当前使用的同一设备上扫描二维码。我在帐户设置中检查了 Google 的做法(通过 Android 上的 Chrome 登录):
因此,默认情况下,他们建议扫描二维码,但当我单击“我不能”时,他们建议我自己复制粘贴秘密。
但为了确保他们跟踪用户是从移动设备登录的,为什么他们不只显示 otpauth:// 链接呢?我尝试在我的应用程序中执行此操作,它的工作方式就像一个魅力(至少在 Android 上,现在无法在 iPhone 上检查,但如果您有机会在 iPhone 上测试它,这里有一个示例链接):
otpauth://totp/test@example.com?secret=wonttellyouthat&algorithm=SHA1&digits=6&period=30&issuer=superwebsite
upd:SOF 不会使其可点击 - 一定是出于安全原因,但在我的网站上我可以毫无问题地执行此操作。当选中“请求桌面站点”复选框时,将其包装到 Android 上的 Chrome 中的代码片段中即可:
<a href="otpauth://totp/test@example.com?secret=wonttellyouthat&algorithm=SHA1&digits=6&period=30&issuer=superwebsite">otpauth://totp/test@example.com?secret=wonttellyouthat&algorithm=SHA1&digits=6&period=30&issuer=superwebsite</a>Run Code Online (Sandbox Code Playgroud)
点击它,Android 会建议我可以使用 Microsoft 或 Google 身份验证器,这意味着 Google 的应用程序支持此技巧。我还安装了 LastPass,但那个并没有弹出。
在我看来,这个解决方案对用户更加友好,并且很好奇为什么谷歌不允许用户这样做?一定有一些我没有考虑到的陷阱吗?
android one-time-password google-authenticator totp multi-factor-authentication
我必须向 URL http://example.com/test发出 HTTP POST 请求,其中包含 JSON 字符串作为正文部分、标头“Content-Type:application/json”和“Authorization: Basic userid:password”。用户 ID 为 abc@example.com,密码必须是 10 位基于时间的一次性密码,符合 RFC6238 TOTP,使用 HMAC-SHA-512 作为哈希函数。
令牌共享密钥应为“abc@example.comTEXT5”,不带双引号。
因此,为了实现上述目标,我修改了 RFC6238 RC6238 TOTP Algo的 Java 代码
为了获得 TOTP,我使用在线转换器工具 以及一些生成相同 128 个字符长度的十六进制代码的代码将共享密钥“abc@example.comTEXT5”转换为 HMAC-SHA512
发出请求总是会回复“TOTP 错误”。
我注意到我生成了错误的密钥,因此 TOTP 是错误的。那么,如何用RFC6238算法的Java代码生成符合HMAC-SHA512的正确密钥呢?
算法有默认密钥作为种子:
String seed64 = "3132333435363738393031323334353637383930" +
"3132333435363738393031323334353637383930" +
"3132333435363738393031323334353637383930" +
"31323334";
Run Code Online (Sandbox Code Playgroud)
我怎样才能为我的共享秘密“abc@example.comTEXT5”获得这样的seed64?我修改后的代码是10 位 TOTP
我感谢大家的帮助!
我最近分配的一个学校项目有一个我们必须完成的编码挑战。该挑战由多个部分组成,最后一部分是上传到私有 GitHub 存储库,并在特定条件下通过发出 POST 请求来提交完成请求。
我已成功完成挑战的其他部分,但仍坚持提交请求。提交作品须遵守以下规则:
构建您的解决方案请求
首先,构造一个 JSON 字符串,如下所示:
{
"github_url": "https://github.com/YOUR_ACCOUNT/GITHUB_REPOSITORY",
"contact_email": "YOUR_EMAIL"
}填写您的电子邮件地址
YOUR_EMAIL,以及包含您的解决方案的私有 Github 存储库YOUR_ACCOUNT/GITHUB_REPOSITORY。然后,向以下 URL 发出 HTTP POST 请求,并将 JSON 字符串作为正文部分。
CHALLENGE_URL内容类型
请求的 Content-Type: 必须是
application/json。授权
URL 受 HTTP 基本身份验证保护,RFC2617 第 2 章对此进行了解释,因此您必须在 POST 请求中提供 Authorization: 标头字段。
- 对于 HTTP 基本身份验证的用户 ID,请使用您在 JSON 字符串中输入的相同电子邮件地址。
- 对于密码,请提供符合 RFC6238 TOTP 的 10 位基于时间的一次性密码。
授权密码
要生成 TOTP 密码,您需要使用以下设置:
- 您必须根据 RFC6238 生成正确的 TOTP 密码
- TOTP
Time Step X是 30 秒。T0是 0。 …
我正在使用 Cognito 用户池来验证我的 Web 应用程序。我现在一切正常,但现在我需要为它启用 MFA。这就是我现在的做法(提供的所有代码都是服务器端代码):
const cognito = new AWS.CognitoIdentityServiceProvider();
cognito.signUp({
ClientId,
Username: email,
Password,
}).promise();
Run Code Online (Sandbox Code Playgroud)
一封电子邮件被发送到用户的地址(在前面的函数调用中称为用户名),其中包含一个代码。
用户读取代码并将代码提供给下一个函数调用:
cognito.confirmSignUp({
ClientId,
ConfirmationCode,
Username: email,
ForceAliasCreation: false,
}).promise();
Run Code Online (Sandbox Code Playgroud)
const tokens = await cognito.adminInitiateAuth({
AuthFlow: 'ADMIN_NO_SRP_AUTH',
ClientId,
UserPoolId,
AuthParameters: {
'USERNAME': email,
'PASSWORD': password,
},
}).promise();
Run Code Online (Sandbox Code Playgroud)
我对这个过程很满意。但是现在我需要为此添加 TOTP MFA 功能。如果我想这样做,有人可以告诉我如何更改这些步骤吗?顺便说一句,我知道在创建用户池时需要为用户池启用 TOTP MFA。我只是询问它如何影响我的注册/登录过程。
我正在尝试使用 totp 在我的应用程序中实现 MFA 身份验证。波纹管是我使用的库。注册用户一切顺利,我收到了二维码,扫描它并每 30 秒在谷歌身份验证器中获取一次代码。当我尝试登录以验证代码时,代码验证不起作用(在身份验证服务中,方法验证)。我花了几个小时但无法弄清楚,尝试了不同的用户、日志但没有成功。
<dependency>
<groupId>dev.samstevens.totp</groupId>
<artifactId>totp</artifactId>
<version>1.7.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这是我的代码
AuthContoller.java
import com.example.jsonfaker.model.dto.LoginRequest;
import com.example.jsonfaker.model.dto.SignupRequest;
import com.example.jsonfaker.model.dto.VerifyRequest;
import com.example.jsonfaker.service.Exporter;
import com.example.jsonfaker.service.UserAuthService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/auth")
@CrossOrigin
public class AuthController {
private final Exporter exporter;
private final UserAuthService userAuthService;
public AuthController(Exporter exporter, UserAuthService userAuthService) {
this.exporter = exporter;
this.userAuthService = userAuthService;
}
@PostMapping("/login")
public ResponseEntity<String> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
String response = userAuthService.login(loginRequest);
return ResponseEntity
.ok()
.body(response); …Run Code Online (Sandbox Code Playgroud) totp ×9
multi-factor-authentication ×4
hmac ×2
java ×2
spring-boot ×2
android ×1
c# ×1
http-headers ×1
https ×1
node.js ×1
qr-code ×1