ฉันต้องการเพิ่มตรวจสอบปัจจัยหลายพร้อมด้วยสัญญาณอ่อน TOTP แอพลิเคชันเชิงมุมและฤดูใบไม้ผลิขณะที่การรักษาทุกอย่างใกล้เคียงเป็นไปได้ที่จะเป็นค่าเริ่มต้นของฤดูใบไม้ผลิ Boot รักษาความปลอดภัยเริ่มต้น
การตรวจสอบความถูกต้องของโทเค็นเกิดขึ้นภายในเครื่อง (ด้วยไลบรารี aerogear-otp-java) ไม่มีผู้ให้บริการ API บุคคลที่สาม
การตั้งค่าโทเค็นสำหรับผู้ใช้ทำงานได้ แต่การตรวจสอบความถูกต้องโดยการใช้ประโยชน์จาก Spring Security Authentication Manager / Providers ไม่ได้
TL; DR
- วิธีการอย่างเป็นทางการในการรวม AuthenticationProvider เพิ่มเติมเข้ากับระบบกำหนดค่าเริ่มต้นของ Spring Boot Securityคืออะไร
- วิธีที่แนะนำในการป้องกันการโจมตีซ้ำคืออะไร?
รุ่นยาว
API มีจุดปลายทาง/auth/token
ที่ส่วนหน้าสามารถรับโทเค็น JWT ได้โดยระบุชื่อผู้ใช้และรหัสผ่าน การตอบสนองยังรวมถึงการตรวจสอบสถานะซึ่งสามารถทั้งรับรองความถูกต้องหรือPRE_AUTHENTICATED_MFA_REQUIRED
หากผู้ใช้ต้องการ MFA โทเค็นจะถูกออกด้วยสิทธิ์ที่ได้รับเพียงครั้งเดียวPRE_AUTHENTICATED_MFA_REQUIRED
และเวลาหมดอายุ 5 นาที สิ่งนี้ช่วยให้ผู้ใช้สามารถเข้าถึงจุดปลาย/auth/mfa-token
ซึ่งพวกเขาสามารถให้รหัส TOTP จากแอพ Authenticator และรับโทเค็นที่ได้รับการรับรองความถูกต้องครบถ้วนเพื่อเข้าถึงเว็บไซต์
ผู้ให้บริการและโทเค็น
ฉันได้สร้างประเพณี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);
}
และ a OneTimePasswordAuthenticationToken
ซึ่งขยายAbstractAuthenticationToken
เพื่อเก็บชื่อผู้ใช้ (นำมาจาก JWT ที่ลงนามแล้ว) และรหัส OTP
การกำหนดค่า
ฉันมีกำหนดเองของฉันWebSecurityConfigurerAdapter
ที่ฉันจะเพิ่มของฉันเองผ่านทางAuthenticationProvider
http.authenticationProvider()
การเข้าสู่ JavaDoc ดูเหมือนจะเป็นสถานที่ที่เหมาะสม:
อนุญาตให้เพิ่ม AuthenticationProvider เพิ่มเติมที่จะใช้
ส่วนที่เกี่ยวข้องใน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
การฉีดและดึงมันทั้งหมดเข้าด้วยกัน
@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
เหตุใด Spring Security จึงไม่มารับผู้ให้บริการรับรองความถูกต้องของฉัน แก้จุดบกพร่องแสดงให้เห็นว่าการควบคุมผมว่าเป็นผู้ให้บริการการตรวจสอบสิทธิ์เฉพาะในDaoAuthenticationProvider
AuthenticationProviderManager
หากฉันเปิดเผยMfaAuthenticationProvider
ว่าเป็น bean ผู้ให้บริการรายเดียวเท่านั้นที่ลงทะเบียนดังนั้นฉันจึงได้สิ่งที่ตรงกันข้าม:
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken.
ดังนั้นฉันจะได้รับทั้งสองได้อย่างไร
คำถามของฉัน
อะไรคือวิธีที่แนะนำในการรวมระบบเพิ่มเติมAuthenticationProvider
เข้าไปในระบบที่กำหนดค่าของSpring Boot Security Starterเพื่อให้ฉันได้รับทั้งDaoAuthenticationProvider
กำหนดเองและของฉันเองMfaAuthenticationProvider
? ฉันต้องการเก็บค่าเริ่มต้นของSpring Boot Scurity Starterและให้ผู้ให้บริการของฉันเองเพิ่มเติม
การป้องกันการโจมตี Replay
ฉันรู้ว่าอัลกอริทึม OTP นั้นไม่ได้ป้องกันตัวเองจากการโจมตีซ้ำในเวลาที่รหัสถูกต้อง; RFC 6238 ทำให้สิ่งนี้ชัดเจน
ตัวตรวจสอบต้องไม่ยอมรับความพยายามครั้งที่สองของ OTP หลังจากการตรวจสอบความถูกต้องสำเร็จสำหรับ OTP แรกซึ่งทำให้มั่นใจได้ว่าจะใช้ OTP ครั้งเดียวเท่านั้น
ฉันสงสัยว่ามีวิธีแนะนำในการใช้การป้องกันไหม เนื่องจากโทเค็น OTP นั้นเป็นไปตามเวลาฉันจึงคิดว่าจะเก็บการเข้าสู่ระบบที่ประสบความสำเร็จครั้งล่าสุดในรูปแบบของผู้ใช้และทำให้แน่ใจว่ามีการเข้าสู่ระบบที่สำเร็จเพียงครั้งเดียวต่อการแบ่งเวลา 30 วินาที หลักสูตรนี้หมายถึงการซิงโครไนซ์กับรุ่นผู้ใช้ มีวิธีใดที่ดีกว่านี้?
ขอบคุณ.
-
PS: เนื่องจากนี่เป็นคำถามเกี่ยวกับความปลอดภัยฉันกำลังมองหาคำตอบจากแหล่งข้อมูลที่น่าเชื่อถือและ / หรือเป็นทางการ ขอบคุณ.