Java Spring Security能否为同一用户接受多个密码?
我在我的应用程序中使用Spring安全机制,用一个密码对用户进行身份验证。我试图满足一个要求,即覆盖密码也将对同一用户进行身份验证Java Spring Security能否为同一用户接受多个密码?,java,spring-security,Java,Spring Security,我在我的应用程序中使用Spring安全机制,用一个密码对用户进行身份验证。我试图满足一个要求,即覆盖密码也将对同一用户进行身份验证 如何使用Spring Security实现这一点?有可能,您必须通过扩展现有的DAAuthenticationProvider来实现自己的AuthenticationProvider(请参见此处的additionalAuthenticationChecks()。 此外,默认情况下,该用户仅与一个密码关联(UserDetails.getPassword()),因此您需
如何使用Spring Security实现这一点?有可能,您必须通过扩展现有的
DAAuthenticationProvider
来实现自己的AuthenticationProvider
(请参见此处的additionalAuthenticationChecks()
。此外,默认情况下,该用户仅与一个密码关联(
UserDetails.getPassword()
),因此您需要该类的一个扩展来保存多个密码,以及一个相应的UserDetailsService
实现,该实现知道如何加载用户及其密码 通过提供多个带有“UserDetailsService”的“AuthenticationProvider”,很容易做到这一点
private DaoAuthenticationProvider userAuthProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setHideUserNotFoundExceptions(false);
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(userDetailsService);
return provider;
}
private DaoAuthenticationProvider superVisorAuthProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setHideUserNotFoundExceptions(false);
provider.setUserDetailsService(supervisorDetailService);
return provider;
}
然后
如前所述,您可以覆盖“additionalAuthenticationChecks” 希望这对别人有帮助
@Slf4j
@Service
class FlexibleAuthenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider {
@Autowired
UserDetailsService userDetailsService
@Autowired
PasswordEncoder passwordEncoder
@PostConstruct
def init() {
super.setPasswordEncoder(passwordEncoder)
super.setUserDetailsService(userDetailsService)
}
@Override
protected void additionalAuthenticationChecks(
UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
try {
super.additionalAuthenticationChecks(userDetails, authentication)
} catch (AuthenticationException e) {
log.error('Unable to authenticate with regular credentials')
try {
def mutableUserDetails = new MutableUser(userDetails)
mutableUserDetails.password = 'alternatepassword'
return super.additionalAuthenticationChecks(mutableUserDetails, authentication)
} catch (AuthenticationException err) {
log.error('Token based authentication failed')
}
throw e
}
}
static class MutableUser implements UserDetails {
private String password
private final UserDetails delegate
MutableUser(UserDetails user) {
this.delegate = user
this.password = user.password
}
String getPassword() {
return password
}
void setPassword(String password) {
this.password = password
}
....
}
}
@Configuration
class AuthWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
FlexibleAuthenticationProvider flexibleAuthenticationProvider
....
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(flexibleAuthenticationProvider)
}
....
}
我实现了自己的AuthenticationProvider,并在重写的authenticate()方法中执行了所需的工作。谢谢你的帮助!有没有关于如何做到这一点的例子?
@Slf4j
@Service
class FlexibleAuthenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider {
@Autowired
UserDetailsService userDetailsService
@Autowired
PasswordEncoder passwordEncoder
@PostConstruct
def init() {
super.setPasswordEncoder(passwordEncoder)
super.setUserDetailsService(userDetailsService)
}
@Override
protected void additionalAuthenticationChecks(
UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
try {
super.additionalAuthenticationChecks(userDetails, authentication)
} catch (AuthenticationException e) {
log.error('Unable to authenticate with regular credentials')
try {
def mutableUserDetails = new MutableUser(userDetails)
mutableUserDetails.password = 'alternatepassword'
return super.additionalAuthenticationChecks(mutableUserDetails, authentication)
} catch (AuthenticationException err) {
log.error('Token based authentication failed')
}
throw e
}
}
static class MutableUser implements UserDetails {
private String password
private final UserDetails delegate
MutableUser(UserDetails user) {
this.delegate = user
this.password = user.password
}
String getPassword() {
return password
}
void setPassword(String password) {
this.password = password
}
....
}
}
@Configuration
class AuthWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
FlexibleAuthenticationProvider flexibleAuthenticationProvider
....
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(flexibleAuthenticationProvider)
}
....
}