繁体   English   中英

通过 LDAP 存储库对 LDAP 进行身份验证

[英]Authenticating LDAP via LDAP Repository

我无法从我的 LDAP 服务器(在 SSHA 中)解析不同的编码类型以及纯文本的身份验证值。

我正在使用 LDAP 存储库来检索我的 LDAP 服务器并使用AuthenticationManager和我自己的 `UserDetailService.

当我尝试进行身份验证时,问题总是会收到错误的凭据异常。

如下面我的代码所示;

当我请求/auth时,我有一个纯文本usernamepassword 但是,当我尝试通过AuthenticationManager对其进行身份验证时,它给了我一个错误的凭据。 现在,我知道这与UserDetailService.getPassword()和我在UsernamePasswordAuthenticationToken中提供的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 服务器)具有不同的 hash。

我使用LdapShaPasswordEncoder.encode对 hash 用户输入的密码。

另外,我注意到每次我想进行身份验证(调用http://locahost:xxxx/auth )时,用户输入的密码 hash 每次都会更改 我认为这在散列时是正常的

安全配置注意:我现在允许所有 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

}

您正在使用 BCryptPasswordEncoder 但在 LDAP 中使用的是 SSHA 加密。

需要修改 class SantaRestApiSecurityConfiguration中的方法passwordEncoder

  @Bean
public PasswordEncoder passwordEncoder() {
   return  new LdapShaPasswordEncoder();

}



public Class UserLdap {

    @Attribute(name = "userPassword", type = Type.BINARY)
    private byte[] password;
}

并更改方法 loadUserByUsername

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        UserLdap e = ldapRepo.findByUid(username);
        logger.info("{}",e.toString());
        String password = "{SSHA}" + new String(e.getPassword());
        return new AuthDetails(e.getCn(), 
                               password,
                               e.getUid(), 
                               e.getMail(), 
                               e.getSn(), 
                               Long.toString( e.getUidNumber()));
    } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM