此方法基于覆盖源码路径实现,以最少的配置完成Spring Security OAuth2实现多用户类型认证与多用户类型token刷新
Spring Security OAuth2实现多用户类型认证(新)
1. 在src/main/java目录下新建org/springframework/security文件夹
2. 继续新建core/userdetails文件夹
3. 新增UserDetailsService接口方法类。
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
UserDetails loadUserByUsername(String var1, String var2) throws UsernameNotFoundException;
}
4. UserDetailsServicesImpl实现类
package com.est.oauth.service;
@Slf4j
@Service
public class UserDetailsServicesImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return null;
}
@Override
public UserDetails loadUserByUsername(String s, String var2) throws UsernameNotFoundException {
return null;
}
}
5. 复制org.springframework.security.authentication.dao.DaoAuthenticationProvider的代码,自定义 CustomAuthenticationProvider,然后进行修改retrieveUser()方法,其他不需要动
package com.tx.tcm.oauth.security.handler;
import com.tx.tcm.oauth.security.service.UserDetailsServices;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.Map;
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
private PasswordEncoder passwordEncoder;
private volatile String userNotFoundEncodedPassword;
@Resource
private UserDetailsServices userDetailsServices;
private UserDetailsPasswordService userDetailsPasswordService;
public CustomAuthenticationProvider() {
this.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder());
}
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (authentication.getCredentials() == null) {
this.logger.debug("Authentication failed: no credentials provided");
throw new ApiException("身份验证失败");
} else {
String presentedPassword = authentication.getCredentials().toString();
if (StringUtils.isBlank(presentedPassword)) {
throw new ApiException("密码不能为空");
}
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
this.logger.debug("Authentication failed: password does not match stored value");
throw new ApiException("密码错误");
}
}
}
protected void doAfterPropertiesSet() {
Assert.notNull(this.userDetailsServices, "A UserDetailsService must be set");
}
protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
this.prepareTimingAttackProtection();
Map<String,String> map = (Map<String, String>) authentication.getDetails();
try {
String userType = map.get("type");
UserDetails loadedUser = getUserDetailsServices().loadUserByUsername(username, userType);
if (loadedUser == null) {
throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
} else {
return loadedUser;
}
} catch (UsernameNotFoundException var4) {
this.mitigateAgainstTimingAttack(authentication);
throw var4;
} catch (InternalAuthenticationServiceException var5) {
throw var5;
} catch (Exception var6) {
throw new InternalAuthenticationServiceException(var6.getMessage(