网站建设制作设计惠州,iis打开wordpress,烟台百度网站建设,Erphpdown wordpress双因素认证#xff08;2FA#xff0c;Two-Factor Authentication#xff09;是一种提高安全性的方法#xff0c;要求用户在登录或进行某些敏感操作时提供两种不同类型的身份验证信息。这种方法通过引入第二层验证#xff0c;增加了账户被未经授权访问的难度。
项目结构
…双因素认证2FATwo-Factor Authentication是一种提高安全性的方法要求用户在登录或进行某些敏感操作时提供两种不同类型的身份验证信息。这种方法通过引入第二层验证增加了账户被未经授权访问的难度。
项目结构
spring-boot-2fa-demo
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── demo
│ │ │ ├── DemoApplication.java
│ │ │ ├── security
│ │ │ │ ├── SecurityConfig.java
│ │ │ │ ├── TotpAuthenticationFilter.java
│ │ │ │ ├── TotpAuthenticationProvider.java
│ │ │ │ ├── TotpAuthenticationToken.java
│ │ │ │ └── TotpAuthenticator.java
│ │ │ └── web
│ │ │ ├── TotpSetupController.java
│ │ │ └── TotpVerifyController.java
│ └── main
│ └── resources
│ └── application.properties
└── pom.xml1. pom.xml
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.example/groupIdartifactIddemo/artifactIdversion0.0.1-SNAPSHOT/versionnamespring-boot-2fa-demo/namedescriptionSpring Boot 2FA Demo/descriptionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.0/versionrelativePath/ !-- lookup parent from repository --/parentdependencies!-- Spring Boot Starter Web --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Spring Boot Starter Security --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!-- TOTP Library --dependencygroupIdde.taimos/groupIdartifactIdtotp/artifactIdversion1.0.0/version/dependency!-- Spring Boot Starter Test --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build
/project2. DemoApplication.java
package com.example.demo; import com.example.demo.demo.security.TotpAuthenticator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext; SpringBootApplication
public class DemoApplication { public static void main(String[] args) { ApplicationContext context SpringApplication.run(DemoApplication.class, args); String[] beanNames context.getBeanNamesForType(TotpAuthenticator.class); for (String beanName : beanNames) { System.out.println(Found bean: beanName); }}
}### 3. Security 配置#### SecurityConfig.javajava
package com.example.demo.demo.security; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; Configuration
EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // 配置不需要认证的路径 .antMatchers(/login, /totp-setup, /totp-verify, /auth/*,/test/*).permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage(/login) .defaultSuccessUrl(/totp-verify) .permitAll() .and() // 在用户名密码过滤器之前添加 TOTP 认证过滤器 .addFilterBefore(new TotpAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); }
}TotpAuthenticationFilter.java
package com.example.demo.demo.security; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; public class TotpAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public TotpAuthenticationFilter() { super(new AntPathRequestMatcher(/totp-verify)); } Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String totp request.getParameter(totp); String username request.getParameter(username); // 创建 TOTP 认证令牌 TotpAuthenticationToken token new TotpAuthenticationToken(username, totp); return this.getAuthenticationManager().authenticate(token); } Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { SecurityContextHolder.getContext().setAuthentication(authResult); chain.doFilter(request, response); }
}#### TotpAuthenticationProvider.javajava
package com.example.demo.demo.security; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService; public class TotpAuthenticationProvider implements AuthenticationProvider { Autowired private TotpAuthenticator totpAuthenticator; Autowired private UserDetailsService userDetailsService; Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username authentication.getName(); String totp (String) authentication.getCredentials(); // 验证 TOTP if (totpAuthenticator.verifyTotp(username, Integer.parseInt(totp))) { return new TotpAuthenticationToken(username, totp, userDetailsService.loadUserByUsername(username).getAuthorities()); } return null; } Override public boolean supports(Class? authentication) { return TotpAuthenticationToken.class.isAssignableFrom(authentication); }
}TotpAuthenticationToken.java
package com.example.demo.demo.security; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import java.util.Collection; public class TotpAuthenticationToken extends AbstractAuthenticationToken { private final Object principal; private Object credentials; public TotpAuthenticationToken(Object principal, Object credentials) { super(null); this.principal principal; this.credentials credentials; setAuthenticated(false); } public TotpAuthenticationToken(Object principal, Object credentials, Collection? extends GrantedAuthority authorities) { super(authorities); this.principal principal; this.credentials credentials; setAuthenticated(true); } Override public Object getCredentials() { return this.credentials; } Override public Object getPrincipal() { return this.principal; } Override public void eraseCredentials() { super.eraseCredentials(); credentials null; }
}
TotpAuthenticator.java
package com.example.demo.demo.security; import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import org.springframework.stereotype.Component; /** * author lei */Component
public class TotpAuthenticator { private final GoogleAuthenticator gAuth new GoogleAuthenticator(); // 生成 TOTP 密钥并返回 GoogleAuthenticatorKey 对象 public GoogleAuthenticatorKey generateSecret() { return gAuth.createCredentials(); } // 获取 TOTP QR 码 URL public String getQRCode(GoogleAuthenticatorKey secret, String account) { return GoogleAuthenticatorQRGenerator.getOtpAuthTotpURL(account, SpringBootDemo, secret); } // 验证 TOTP public boolean verifyTotp(String secret, int verificationCode) { return gAuth.authorize(secret, verificationCode); }
}
4. 控制器
TotpSetupController.java
package com.example.demo.demo.web; import com.example.demo.demo.dto.QRCodeResponse;
import com.example.demo.demo.security.TotpAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import org.springframework.web.bind.annotation.*; import java.util.HashMap;
import java.util.Map; RestController
RequestMapping(/auth)
public class TotpSetupController { private final TotpAuthenticator totpAuthenticator; public TotpSetupController(TotpAuthenticator totpAuthenticator) { this.totpAuthenticator totpAuthenticator; } // 设置 TOTP 密钥并返回 QR 码 URL GetMapping(/totp-setup) public MapString, String setupTotp(RequestParam String username) { // 写死一个 TOTP 密钥 String hardCodedSecret OZSNQGV44RGY63BL; GoogleAuthenticatorKey googleAuthenticatorKey new GoogleAuthenticatorKey.Builder(hardCodedSecret).build(); String qrCodeUrl totpAuthenticator.getQRCode(googleAuthenticatorKey, username); MapString, String response new HashMap(); response.put(secret, hardCodedSecret); response.put(qrCodeUrl, qrCodeUrl); return response; } // 设置 TOTP 密钥并返回 QR 码 URL GetMapping(/totp-setup1) public QRCodeResponse setupTotp1(RequestParam String username) { GoogleAuthenticatorKey googleAuthenticatorKey totpAuthenticator.generateSecret(); // 保存密钥与用户名的关联关系可以使用数据库等存储 // 这里只是示例没有实际存储 String qrCodeUrl totpAuthenticator.getQRCode(googleAuthenticatorKey, username); return new QRCodeResponse(googleAuthenticatorKey.getKey(), qrCodeUrl); }
}TotpVerifyController.java
package com.example.demo.demo.web; import com.example.demo.demo.security.TotpAuthenticator;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*; RestController
RequestMapping(/test)
public class TotpVerifyController { private final TotpAuthenticator totpAuthenticator; public TotpVerifyController(TotpAuthenticator totpAuthenticator) { this.totpAuthenticator totpAuthenticator; } GetMapping(/totp-verify) public String verifyTotp(RequestParam int totp) { String username SecurityContextHolder.getContext().getAuthentication().getName(); // 从存储中获取与用户名关联的密钥这里假设已获取 String secret OZSNQGV44RGY63BL; if (totpAuthenticator.verifyTotp(secret, totp)) { return 2FA 成功!; } else { return 无效的 TOTP!; } } GetMapping(/test1) public String test() { return hell1; }}5. 配置文件
application.properties
server.port8080
spring.application.name2FA-Demo6. 启动项目
确保所有代码都已编写完成然后运行 DemoApplication.java 启动项目。你可以通过以下步骤测试 2FA 功能
访问 /totp-setup 端点生成 TOTP 密钥和 QR 码。使用 Google Authenticator 扫描 QR 码。访问 /totp-verify 端点并输入 Google Authenticator 生成的一次性密码。
接口输出url可通过二下面工具生成二维码工具https://www.runoob.com/try/try.php?filenametryhtml5_QRCode