- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想向 Angular 和 Spring 应用程序添加使用 TOTP 软 token 的多因素身份验证,同时使所有内容尽可能接近 Spring Boot Security Starter 的默认值。
token 验证在本地进行(使用 aerogear-otp-java 库),没有第三方 API 提供者。
为用户设置 token 是可行的,但通过利用 Spring Security Authentication Manager/Providers 来验证它们却不行。
TL;博士
/auth/token
前端可以通过提供用户名和密码从中获取 JWT token 。响应还包括一个身份验证状态,可以是
。已认证 或
PRE_AUTHENTICATED_MFA_REQUIRED .
PRE_AUTHENTICATED_MFA_REQUIRED
的单一授权权限颁发 token 。和 5 分钟的过期时间。这允许用户访问端点
/auth/mfa-token
他们可以从他们的 Authenticator 应用程序中提供 TOTP 代码并获取完全经过身份验证的 token 以访问该站点。
MfaAuthenticationProvider
实现
AuthenticationProvider
:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// validate the OTP code
}
@Override
public boolean supports(Class<?> authentication) {
return OneTimePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
OneTimePasswordAuthenticationToken
扩展
AbstractAuthenticationToken
保存用户名(取自签名的 JWT)和 OTP 代码。
WebSecurityConfigurerAdapter
,我在其中添加我的自定义
AuthenticationProvider
通过
http.authenticationProvider()
.根据 JavaDoc,这似乎是正确的地方:
Allows adding an additional AuthenticationProvider to be used
SecurityConfig
看起来像这样。
@Configuration
@EnableWebSecurity
@EnableJpaAuditing(auditorAwareRef = "appSecurityAuditorAware")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final TokenProvider tokenProvider;
public SecurityConfig(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(new MfaAuthenticationProvider());
http.authorizeRequests()
// Public endpoints, HTML, Assets, Error Pages and Login
.antMatchers("/", "favicon.ico", "/asset/**", "/pages/**", "/api/auth/token").permitAll()
// MFA auth endpoint
.antMatchers("/api/auth/mfa-token").hasAuthority(ROLE_PRE_AUTH_MFA_REQUIRED)
// much more config
AuthController
有
AuthenticationManagerBuilder
注入(inject)并将其拉到一起。
@RestController
@RequestMapping(AUTH)
public class AuthController {
private final TokenProvider tokenProvider;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
public AuthController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
this.tokenProvider = tokenProvider;
this.authenticationManagerBuilder = authenticationManagerBuilder;
}
@PostMapping("/mfa-token")
public ResponseEntity<Token> mfaToken(@Valid @RequestBody OneTimePassword oneTimePassword) {
var username = SecurityUtils.getCurrentUserLogin().orElse("");
var authenticationToken = new OneTimePasswordAuthenticationToken(username, oneTimePassword.getCode());
var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
// rest of class
/auth/mfa-token
发布导致此错误:
"error": "Forbidden",
"message": "Access Denied",
"trace": "org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for de.....OneTimePasswordAuthenticationToken
DaoAuthenticationProvider
是
AuthenticationProviderManager
中唯一的身份验证提供程序.
MfaAuthenticationProvider
作为bean,它是唯一注册的提供者,所以我得到相反的结果:
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken.
AuthenticationProvider
的推荐方法是什么?进入一个 Spring Boot Security Starter 配置的系统,这样我就得到了
DaoAuthenticationProvider
和我自己的定制
MfaAuthenticationProvider
?我想保留 Spring Boot Scurity Starter 的默认值并另外拥有自己的 Provider。
The verifier MUST NOT accept the second attempt of the OTP after the successful validation has been issued for the first OTP, which ensures one-time only use of an OTP.
最佳答案
为了回答我自己的问题,经过进一步研究,这就是我实现它的方式。
我有一个提供者作为实现 AuthenticationProvider
的 pojo .它故意不是 Bean/组件。否则 Spring 会将其注册为唯一的 Provider。
public class MfaAuthenticationProvider implements AuthenticationProvider {
private final AccountService accountService;
@Override
public Authentication authenticate(Authentication authentication) {
// here be code
}
AuthenticationManagerBuilder
并手动注入(inject)我的
MfaAuthenticationProvider
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
@Override
protected void configure(HttpSecurity http) throws Exception {
// other code
authenticationManagerBuilder.authenticationProvider(getMfaAuthenticationProvider());
// more code
}
// package private for testing purposes.
MfaAuthenticationProvider getMfaAuthenticationProvider() {
return new MfaAuthenticationProvider(accountService);
}
/auth/mfa-token
.
authenticate()
authenticationManagerBuilder 的方法,它选择
MfaAuthenticationProvider
因为它可以处理
OneTimePasswordAuthenticationToken
.
var authenticationToken = new OneTimePasswordAuthenticationToken(usernameFromJwt, providedOtp);
var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
关于spring-boot - 使用 Spring Boot 2 和 Spring Security 5 进行多因素身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59918013/
我正在使用SQL Server 2008 R2,并且想创建一个触发器。 对于每个添加(仅添加),将像这样更新一列: ABC-CurrentYear-AutoIncrementCode 例子: ABC-
是否可以在显示最终一致性的数据存储中创建/存储用户帐户? 似乎不可能在没有一堆架构复杂性的情况下管理帐户创建,以避免可能发生具有相同 UID(例如电子邮件地址)的两个帐户的情况? 最终一致性存储的用户
您好, 我有一个带有 Identity 的 .NetCore MVC APP并使用 this指导我能够创建自定义用户验证器。 public class UserDomainValidator : IU
这与以下问题相同:HiLo or identity? 我们以本站的数据库为例。 假设该站点具有以下表格: 帖子。 投票。 注释。 使用它的最佳策略是什么: 身份 - 这是更常见的。 或者 HiLo -
我想将 Blazor Server 与 ASP.NET Identity 一起使用。但我需要使用 PostgreSQL 作为用户/角色存储,因为它在 AWS 中。 它不使用 EF,这是我需要的。 我创
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我使用 ASP.NET 身份和 ClaimsIdentity 来验证我的用户。当用户通过身份验证时,属性 User.Identity 包含一个 ClaimsIdentity 实例。 但是,在登录请求期
所以我在两台机器上都安装了 CYGWIN。 如果我这样做,它会起作用: ssh -i desktop_rsa root@remoteserver 这需要我输入密码 ssh root@remoteser
我尝试在 mac osx 上的终端中通过 telnet 连接到 TOR 并请求新身份,但它不起作用,我总是收到此错误消息: Trying 127.0.0.1... telnet: connect to
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我正在开发一项服务,客户可以在其中注册他们的 webhook URL,我将发送有关已注册 URL 的更新。为了安全起见,我想让客户端(接收方)识别是我(服务器)向他们发送请求。 Facebook和 G
在 Haskell 中,有没有办法测试两个 IORef 是否相同?我正在寻找这样的东西: IORef a -> IORef a -> IO Bool 例如,如果您想可视化由 IORef 组成的图形,这
我是 .NET、MVC 和身份框架的新手。我注意到身份框架允许通过注释保护单个 Controller 操作。 [Authorize] public ActionResult Edit(int? Id)
我有一列具有身份的列,其计数为19546542,我想在删除所有数据后将其重置。我需要类似ms sql中的'dbcc checkident'这样的内容,但在Oracle中 最佳答案 在Oracle 12
这是我用来创建 session 以发送电子邮件的代码: props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enabl
我想了解 [AllowAnonymous] 标签的工作原理。 我有以下方法 [HttpGet] public ActionResult Add() { return View(); } 当我没
在使用沙盒测试环境时,PayPal 身份 token 对某些人显示而不对其他人显示的原因是否有任何原因。 我在英国使用 API,终生无法生成或找到 token 。 我已经遵循协议(protocol)并
我对非常简单的事情有一些疑问:IDENTITY。我尝试在 phpMyAdmin 中创建表: CREATE TABLE IF NOT EXISTS typEventu ( typEventu
习语 #1 和 #5 是 FinnAPL Idiom Library两者具有相同的名称:“Progressive index of (without replacement)”: ((⍴X)⍴⍋⍋X⍳
当我第一次在 TFS 中设置时,我的公司拼错了我的用户名。此后他们将其更改为正确的拼写,但该更改显然未反射(reflect)在 TFS 中。当我尝试 checkin 更改时,出现此错误: 有没有一种方
我是一名优秀的程序员,十分优秀!