【发布时间】:2020-07-24 19:48:06
【问题描述】:
我无法从我的 LDAP 服务器(在 SSHA 中)解析不同的编码类型以及纯文本的身份验证值。
我正在使用 LDAP 存储库来检索我的 LDAP 服务器,并使用了AuthenticationManager 和我自己的 `UserDetailService.
当我尝试进行身份验证时,问题总是会收到错误的凭据异常。
如下面的代码所示;
当我请求/auth 时,我有一个纯文本username 和password。但是,当我尝试通过AuthenticationManager 对其进行身份验证时,它给了我一个错误的凭据。现在,我知道这与我在UsernamePasswordAuthenticationToken 中提供的UserDetailService.getPassword() 和password 有关。它关于不同的加密类型。我的 LDAP 有一个 {SSHA},也翻译成二进制(字节),编码器是 Bcrypt 和 String。
现在我的问题是,您如何针对 LdapRespository 返回的密码正确地验证密码?
更新
2020-04-12 17:09:46.655 INFO 6672 --- [nio-8080-exec-1] s.w.s.SantaRestApiSecurityConfiguration : Raw Password: jdoe123 | Encoded Password: {SSHA}kMgk3gD4prAa/9m4wsPbuAoGhO7UvH2v6+W0Dg==
2020-04-12 17:09:58.110 INFO 6672 --- [nio-8080-exec-1] s.w.s.SantaRestApiSecurityConfiguration : Raw Password: {SSHA}kMgk3gD4prAa/9m4wsPbuAoGhO7UvH2v6+W0Dg== matches Encoded Password: {SSHA}k1Pp3NICHbwuxFFdT7zno/iG/NTILZGL = false
以上日志是在PasswordEncoder 的密码匹配期间。以此为基础。它表明 原始密码(由用户输入)与 编码密码(来自 ldap 服务器)具有不同的哈希值。
我使用LdapShaPasswordEncoder.encode 对用户输入的密码进行哈希处理。
另外,我注意到每次我想进行身份验证(调用http://locahost:xxxx/auth)时,用户每次都输入密码的哈希更改。我认为哈希时这是正常的
安全配置 注意:我现在允许所有 REST-API 端点,稍后我会限制它
@Configuration
@EnableWebSecurity
public class SantaRestApiSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
AuthService authService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(authService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.csrf()
.disable()
.authorizeRequests().antMatchers("/*").permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/*");
}
/*
* i am not sure about this since my LDAP server has
* a SSHA password encrpytion
*
* */
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
登录控制器
@RestController
@RequestMapping("/auth")
public class LoginController {
public static Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
private AuthenticationManager authManager;
@PostMapping
public ResponseEntity<String> login(@RequestBody Map<String, String> credentials) {
String username = credentials.get("username");
String password = credentials.get("password");
authManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
return new ResponseEntity<String>("", HttpStatus.OK);
}
}
UserDetailService 实现
@Service
public class AuthService implements UserDetailsService {
public static Logger logger = LoggerFactory.getLogger(AuthService.class);
@Autowired
UserLdapRepository ldapRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserLdap e = ldapRepo.findByUid(username);
logger.info("{}",e.toString());
return new AuthDetails(e.getCn(),
e.getPassword(),
e.getUid(),
e.getMail(),
e.getSn(),
Long.toString( e.getUidNumber()));
}
}
UserDetails 实现
public class AuthDetails implements UserDetails {
public static Logger logger = LoggerFactory.getLogger(AuthDetails.class);
private String username;
private String password;
private String email;
private String uidNumber;
private String sn;
private String uid;
public AuthDetails(String username, String password, String uid, String email,String sn, String uidNumber) {
this.uid = uid;
this.password = password;
this.username = username;
this.email = email;
this.sn = sn;
this.uidNumber = uidNumber;
}
/*
* Here i am not sure how to implement this one to satisfy AuthenticationManager
*
*
**/
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return this.username;
}
// some method to implement
}
【问题讨论】:
-
您是否将 LDAP 用户密码存储在 BCrypt 加密中?
-
不,我只是在读取现有的 LDAP 服务器。不写入或修改现有数据。现在,我正在阅读的 LDAP 服务器是 SSHA 加密的。
标签: java spring-boot spring-security spring-data spring-security-ldap