gpt4 book ai didi

java - Spring 安全切换到 Ldap 身份验证和数据库权限

转载 作者:IT老高 更新时间:2023-10-28 13:51:39 25 4
gpt4 key购买 nike

我为我的网页和 Web 服务实现了数据库身份验证。它对两者都有效,现在我必须添加 Ldap 身份验证。我必须通过远程 Ldap 服务器进行身份验证(使用用户名和密码),如果用户存在,我必须使用我的数据库作为用户角色(在我的数据库中,用户名与 Ldap 的用户名相同)。所以我必须从我的实际代码切换到如上所述的 Ldap 和数据库身份验证。我的代码是:安全配置类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}

@Configuration
@Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/client/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}

@Configuration
@Order(2)
public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

@Override
public void configure(WebSecurity web) throws Exception {
web
//Spring Security ignores request to static resources such as CSS or JS files.
.ignoring()
.antMatchers("/static/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() //Authorize Request Configuration
//the / and /register path are accepted without login
//.antMatchers("/", "/register").permitAll()
//the /acquisition/** need admin role
//.antMatchers("/acquisition/**").hasRole("ADMIN")
//.and().exceptionHandling().accessDeniedPage("/Access_Denied");
//all the path need authentication
.anyRequest().authenticated()
.and() //Login Form configuration for all others
.formLogin()
.loginPage("/login")
//important because otherwise it goes in a loop because login page require authentication and authentication require login page
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll();
// CSRF tokens handling
}
}

MyUserDetailsS​​ervice 类

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

@Autowired
private UserServices userServices;
static final Logger LOG = LoggerFactory.getLogger(MyUserDetailsService.class);

@Transactional(readOnly=true)
@Override
public UserDetails loadUserByUsername(final String username){
try{
com.domain.User user = userServices.findById(username);
if (user==null)
LOG.error("Threw exception in MyUserDetailsService::loadUserByUsername : User doesn't exist" );
else{
List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
return buildUserForAuthentication(user, authorities);
}
}catch(Exception e){
LOG.error("Threw exception in MyUserDetailsService::loadUserByUsername : " + ErrorExceptionBuilder.buildErrorResponse(e)); }
return null;
}

// Converts com.users.model.User user to
// org.springframework.security.core.userdetails.User
private User buildUserForAuthentication(com.domain.User user, List<GrantedAuthority> authorities) {
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
}

private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {

Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

// Build user's authorities
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getUserRoleKeys().getRole()));
}

List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

return Result;
}

所以我必须:

1) 用户从网页的登录页面和网络服务的用户名和密码访问。这必须通过 Ldap 完成。

2) 数据库查询需要用户的用户名来认证用户。你知道我该如何实现吗?谢谢

使用正确的代码更新:在@M 之后。 Deinum 建议我创建 MyAuthoritiesPopulator 类而不是 MyUserDetailsS​​ervice 并使用数据库和 Ldap 进行身份验证:

    @Service("myAuthPopulator")
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {

@Autowired
private UserServices userServices;
static final Logger LOG = LoggerFactory.getLogger(MyAuthoritiesPopulator.class);

@Transactional(readOnly=true)
@Override
public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
try{
com.domain.User user = userServices.findById(username);
if (user==null)
LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : User doesn't exist into ATS database" );
else{
for(UserRole userRole : user.getUserRole()) {
authorities.add(new SimpleGrantedAuthority(userRole.getUserRoleKeys().getRole()));
}
return authorities;
}
}catch(Exception e){
LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : " + ErrorExceptionBuilder.buildErrorResponse(e)); }
return authorities;
}
}

我将 SecurityConfig 更改如下:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
@Qualifier("myAuthPopulator")
LdapAuthoritiesPopulator myAuthPopulator;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

auth.ldapAuthentication()
.contextSource()
.url("ldap://127.0.0.1:10389/dc=example,dc=com")
// .managerDn("")
// .managerPassword("")
.and()
.userSearchBase("ou=people")
.userSearchFilter("(uid={0})")
.ldapAuthoritiesPopulator(myAuthPopulator);
}

@Configuration
@Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/client/**")
.authorizeRequests()
//Excluede send file from authentication because it doesn't work with spring authentication
//TODO add java authentication to send method
.antMatchers(HttpMethod.POST, "/client/file").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}

@Configuration
@Order(2)
public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

@Override
public void configure(WebSecurity web) throws Exception {
web
//Spring Security ignores request to static resources such as CSS or JS files.
.ignoring()
.antMatchers("/static/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() //Authorize Request Configuration
//the "/" and "/register" path are accepted without login
//.antMatchers("/", "/register").permitAll()
//the /acquisition/** need admin role
//.antMatchers("/acquisition/**").hasRole("ADMIN")
//.and().exceptionHandling().accessDeniedPage("/Access_Denied");
//all the path need authentication
.anyRequest().authenticated()
.and() //Login Form configuration for all others
.formLogin()
.loginPage("/login")
//important because otherwise it goes in a loop because login page require authentication and authentication require login page
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll();
}
}
}

我在 Apache directory studio 中创建的 LDAP 开发环境

ldap

最佳答案

Spring Security 已经支持 LDAP 开箱即用。它实际上有一个 whole chapter关于这个。

要使用和配置 LDAP,请添加 spring-security-ldap 依赖项,然后使用 AuthenticationManagerBuilder.ldapAuthentication配置它。 LdapAuthenticationProviderConfigurer允许您设置所需的东西。

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.contextSource()
.url(...)
.port(...)
.managerDn(...)
.managerPassword(...)
.and()
.passwordEncoder(passwordEncoder())
.userSearchBase(...)
.ldapAuthoritiesPopulator(new UserServiceLdapAuthoritiesPopulater(this.userService));
}

类似的东西(它至少应该让您了解什么/如何配置东西)还有更多选项,但请查看 javadocs。如果您不能按原样使用 UserService 来检索角色(因为只有角色在数据库中),请实现您自己的 LdapAuthoritiesPopulator为此。

关于java - Spring 安全切换到 Ldap 身份验证和数据库权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34658534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com