我想在我现有的 spring 项目中添加两步验证。到现在为止,我正在检查用户名和密码,如果凭据正确,则用户已登录。我想要的是,如果凭据正确,则应将 otp 发送到电子邮件并呈现 otp 验证表。如果用户输入正确的 otp,那么他应该登录。我添加了 CustomAuthenticationProvider 和 CustomAuthenticationSuccessHandler 。
我的 SecurityConfiguration 的相关部分如下所示。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Autowired
@Qualifier("customUserDetailsService")
UserDetailsService userDetailService;
@Autowired
AuthenticationSuccessHandlerImpl successHandler;
@Autowired
@Qualifier("tokenRepositoryDao")
PersistentTokenRepository tokenRepository;
@Autowired
@Qualifier("customAuthenticationProvider")
AuthenticationProvider authenticationProvider;
private static String key = "rem-me-key";
@Bean
public RememberMeServices rememberMeServices() throws Exception {
return new CustomRememberMeService(key, userDetailService, tokenRepository);
}
@Autowired
protected void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService);
auth.authenticationProvider(authenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login","/loginVerify" ,"/public/**","/KMD/**","/forgetPassword/**","/changePswd/**","/verifyOtp/**").permitAll()
.antMatchers("/","/common/**","/logout/**", "/accessDenied/**").access("hasRole('Admin') or hasRole('NormalUser') ")
.antMatchers("/normalUser/**").access("hasRole('NormalUser')")
.antMatchers("/device/**","/softwares/**","/manual/**","/user/**","/addNewUser/**","/manageUser/**","/manageUserEdit/**",
"/addNewDevice/**","/manageDevice/**","/addNewSoftManual/**","/editUserPage/**","/view/**").access("hasRole('Admin')")
.and()
.csrf().disable()
.formLogin().loginPage("/login").loginProcessingUrl("/checkLoginAction").usernameParameter("username").passwordParameter("password")
.successHandler(successHandler)
.and()
.rememberMe().key("rem-me-key").authenticationSuccessHandler(successHandler).rememberMeParameter("remember-me").rememberMeServices(rememberMeServices())
.tokenRepository(tokenRepository).tokenValiditySeconds(86400).alwaysRemember(true)
.and()
.exceptionHandling().accessDeniedPage("/accessDenied");
}
}
这是 CustomAuthenticationProvider 中编写的代码
@Override
public Authentication authenticate(Authentication authentication) {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
String hashPassword = null ;
UsernamePasswordAuthenticationToken token = null;
try {
hashPassword = LoadParam.generateHash(password.trim(), name.trim());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(password)) {
try {
UserDetails userDetail = null;
try {
userDetail = userDetailService.loadUserByUsername(name);
if(!userDetail.isEnabled()) {
return null;
}
if(hashPassword.matches(userDetail.getPassword())) {
token = new UsernamePasswordAuthenticationToken(userDetail,userDetail.getPassword(), userDetail.getAuthorities());
token.setDetails(userDetail);
}
else {
return null;
}
}
catch (Exception e) {
stringWriter = new StringWriter();
printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
logger.error(stringWriter.toString());
}
return token;
}
catch (UsernameNotFoundException exception) {
return new UsernamePasswordAuthenticationToken(name, password, new ArrayList<>());
}
}
else {
return new UsernamePasswordAuthenticationToken(name, password, new ArrayList<>());
}
}
这是我的 CustomUserDetailService 代码
@Service("customUserDetailsService")
public class CustomUserDetailService implements UserDetailsService {
@Autowired
@Qualifier("commonDAOImpl")
private CommonDAO commonDAO;
@Override
public UserDetails loadUserByUsername(String username ) throws UsernameNotFoundException {
HashMap<String, Object> hashMap = new HashMap<>();
TblUser tblUser = null;
hashMap = commonDAO.findUserByUserId(username, hashMap);
if(hashMap.get("status").equals("0")) {
throw new UsernameNotFoundException("User Not Found");
}
else {
tblUser = (TblUser) hashMap.get("tblUser");
UserDetails userDetails = new User(tblUser.getEmailId(), tblUser.getPassword(),
tblUser.isEnabled(), true, true, true, getGrantedAuthorities((List<TblUserRole>) hashMap.get("roles")));
return userDetails;
}
}
private List<GrantedAuthority> getGrantedAuthorities(List<TblUserRole> tblUserRoles){
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(TblUserRole tblUserRole : tblUserRoles) {
authorities.add(new SimpleGrantedAuthority("ROLE_"+ tblUserRole.getTblRole().getRoleName() ));
}
return authorities;
}
}
我不明白如何处理重定向。请建议我如何实现这一点。如果有人可以为我提供一些帮助,我将不胜感激。