Tôi đang xây dựng một ứng dụng với Spring Boot có tích hợp với LDAP. Tôi đã có thể kết nối thành công với máy chủ LDAP và xác thực người dùng. Bây giờ tôi có một yêu cầu để thêm chức năng nhớ-tôi. Tôi đã cố gắng để xem xét thông qua các bài viết khác nhau (this) nhưng không thể tìm thấy một câu trả lời cho vấn đề của tôi. Official Xuân An document khẳng định rằngSpring Security LDAP và Ghi nhớ tôi
Nếu bạn đang sử dụng một nhà cung cấp chứng thực mà không sử dụng một UserDetailsService (ví dụ, các nhà cung cấp LDAP) sau đó nó sẽ không làm việc trừ khi bạn cũng có một bean UserDetailsService trong ứng dụng của bạn bối cảnh
đây mã làm việc của tôi với một vài suy nghĩ ban đầu để thêm nhớ-me chức năng:
WebSecurityConfig
import com.ui.security.CustomUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.event.LoggerListener;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
String DOMAIN = "ldap-server.com";
String URL = "ldap://ds.ldap-server.com:389";
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/ui/**").authenticated()
.antMatchers("/", "/home", "/UIDL/**", "/ui/**").permitAll()
.anyRequest().authenticated()
;
http
.formLogin()
.loginPage("/login").failureUrl("/login?error=true").permitAll()
.and().logout().permitAll()
;
// Not sure how to implement this
http.rememberMe().rememberMeServices(rememberMeServices()).key("password");
}
@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder
.authenticationProvider(activeDirectoryLdapAuthenticationProvider())
.userDetailsService(userDetailsService())
;
}
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(DOMAIN, URL);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUserDetailsContextMapper(userDetailsContextMapper());
return provider;
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
UserDetailsContextMapper contextMapper = new CustomUserDetailsServiceImpl();
return contextMapper;
}
/**
* Impl of remember me service
* @return
*/
@Bean
public RememberMeServices rememberMeServices() {
// TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("password", userService);
// rememberMeServices.setCookieName("cookieName");
// rememberMeServices.setParameter("rememberMe");
return rememberMeServices;
}
@Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
}
CustomUserDetailsServiceImpl
public class CustomUserDetailsServiceImpl implements UserDetailsContextMapper {
@Autowired
SecurityHelper securityHelper;
Log ___log = LogFactory.getLog(this.getClass());
@Override
public LoggedInUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> grantedAuthorities) {
LoggedInUserDetails userDetails = null;
try {
userDetails = securityHelper.authenticateUser(ctx, username, grantedAuthorities);
} catch (NamingException e) {
e.printStackTrace();
}
return userDetails;
}
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
}
}
tôi biết rằng tôi cần phải thực hiện UserService bằng cách nào đó, nhưng không chắc chắn làm thế nào mà có thể đạt được.
Câu trả lời hay Vladimír! câu hỏi nhanh. Trong dòng mã này: PersistentTokenBasedRememberMeServices services = new PersistentTokenBasedRememberMeServices (staticKey, rememberMeUserDetailsService, rememberMeTokenRepository); Tôi giả định rằng "staticKey" giống với "internalSecretKey". Đúng không? – Maksim
Vâng, đó là cùng một khóa - nó được sử dụng để xác minh rằng RememberMeAuthenticationToken được xây dựng với kiến thức về bí mật này và được xác minh trong RememberMeAuthenticationProvider. Hãy chắc chắn rằng bạn đang sử dụng phiên bản mới nhất của câu trả lời của tôi, bởi vì trong văn bản hiện tại ở trên nó được gọi là "internalSecretKey" ở tất cả các nơi. –
Tuyệt vời, cảm ơn bạn rất nhiều! Làm tất cả mọi việc! – Maksim