无法将java.lang.String转换为org.springframework.security.ldap.userdetails.LdapUserDetails
我设法配置了OAuth2和ldap授权。通过实现LdapUserDetails创建自定义LdapUser,通过实现UserDetailsContextMapper创建CustomUserDetailsContextMapper。 最终,当通过Active Directory用户名和密码进行授权时,我获得了访问令牌 但问题是,我无法从SecurityContextHolder.getContext().getAuthentication()获取当前登录的用户 java.lang.String不能强制转换为LdapUser 下面是我的安全配置:无法将java.lang.String转换为org.springframework.security.ldap.userdetails.LdapUserDetails,java,spring-boot,spring-security-oauth2,spring-ldap,Java,Spring Boot,Spring Security Oauth2,Spring Ldap,我设法配置了OAuth2和ldap授权。通过实现LdapUserDetails创建自定义LdapUser,通过实现UserDetailsContextMapper创建CustomUserDetailsContextMapper。 最终,当通过Active Directory用户名和密码进行授权时,我获得了访问令牌 但问题是,我无法从SecurityContextHolder.getContext().getAuthentication()获取当前登录的用户 java.lang.String不能强
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(adAuthenticationProvider())
.ldapAuthentication()
.userSearchBase("ldap.searchbase").userSearchFilter("ldap.filter").groupSearchFilter("ldap.groupsearch")
.contextSource(contextSource())
.userDetailsContextMapper(userDetailsContextMapper())
.passwordCompare()
.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
@Bean
public DefaultSpringSecurityContextSource contextSource() {
return new DefaultSpringSecurityContextSource(Arrays.asList("ldap.url"), "dc=smth,dc=com");
}
@Bean
public ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("smth.com","ldap.url");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUserDetailsContextMapper(userDetailsContextMapper());
return provider;
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new CustomUserDetailsContextMapper();
}
自定义LdapUser:
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.ldap.userdetails.LdapUserDetails;
import java.util.Collection;
public class LdapUser implements LdapUserDetails
{
private String commonName;
private LdapUserDetails ldapUserDetails;
public LdapUser(LdapUserDetails ldapUserDetails) {
this.ldapUserDetails = ldapUserDetails;
}
@Override
public String getDn() {
return ldapUserDetails.getDn();
}
@Override
public void eraseCredentials() {
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return ldapUserDetails.getAuthorities();
}
@Override
public String getPassword() {
return ldapUserDetails.getPassword();
}
@Override
public String getUsername() {
return ldapUserDetails.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return ldapUserDetails.isAccountNonExpired();
}
@Override
public boolean isAccountNonLocked() {
return ldapUserDetails.isAccountNonLocked();
}
@Override
public boolean isCredentialsNonExpired() {
return ldapUserDetails.isCredentialsNonExpired();
}
@Override
public boolean isEnabled() {
return ldapUserDetails.isEnabled();
}
}
public LdapUser getCurrentLdapUser() {
org.springframework.security.core.context.SecurityContext securityContext = SecurityContextHolder
.getContext();
Authentication authentication = securityContext.getAuthentication();
LdapUser user = null;
if (authentication != null) {
user = ((LdapUser) authentication.getPrincipal());
}
return user;
}
调用此函数后,我得到了转换错误。当我尝试获取主体名称时,它返回-anonymousUser。我不知道为什么它不返回我LdapUser好的,我得到了答案。错过了基本的东西。 因为我没有配置资源服务器(ResourceServerConfigurerAdapter),所以每个登录的Active Directory用户都被视为匿名用户。这就是为什么安全上下文返回字符串user而不是我的自定义Ldap用户 下面是一个ResourceServerConfig示例,以防有人需要:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.resourceId(RESOURCE_ID)
.stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api/**").hasAnyAuthority("Authority_1","Authority_2")
.and().exceptionHandling().authenticationEntryPoint(new UnauthorizedHandler())
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler());
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
}
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.resourceId(RESOURCE_ID)
.stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api/**").hasAnyAuthority("Authority_1","Authority_2")
.and().exceptionHandling().authenticationEntryPoint(new UnauthorizedHandler())
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler());
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
}