Использование LDAP-authentication в JHIPSTER
пытаюсь использовать LDAP аутентификацию в паре с SpringSecurity приложения JHipster, но получаю ошибку A granted authority textual representation is required.
Приложение делает отправку запроса на локально-установленный ADS сервер с уже зашитыми пользователями, но при создании JWT-token не устанавливается роль - org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f4f03bd0: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@b0fc414: Dn: cn=Admin,dc=example,dc=com; Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities
SecurityConfiguration :
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchFilter("(uid={0})")
.groupSearchFilter("member={0}")
.contextSource(getContextSource());
}
@Bean
public LdapContextSource getContextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldap://localhost:10389");
contextSource.setBase("dc=example,dc=com");
contextSource.setUserDn("cn=Admin,dc=example,dc=com");
contextSource.setPassword("admin");
contextSource.afterPropertiesSet(); //needed otherwise you will have a NullPointerException in spring
return contextSource;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/h2-console/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
.and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
.and()
.frameOptions()
.deny()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/prometheus").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.httpBasic()
.and()
.apply(securityConfigurerAdapter());
// @formatter:on
}
private JWTConfigurer securityConfigurerAdapter() {
return new JWTConfigurer(tokenProvider);
}
}
CustomAuthenticationManager :
@Component
public class CustomAuthenticationManager implements AuthenticationManager {
LdapAuthenticationProvider provider = null;
private static final Logger log = LoggerFactory.getLogger(CustomAuthenticationManager.class);
private final UserRepository userRepository;
@Autowired
private final LdapContextSource ldapContextSource;
public CustomAuthenticationManager(UserRepository userRepository, LdapContextSource ldapContextSource) {
this.userRepository = userRepository;
this.ldapContextSource = ldapContextSource;
}
@Override
public Authentication authenticate(Authentication authentication) {
log.debug("AUTHENTICATION Login" + authentication.getName());
log.debug("AUTHENTICATION Password" + authentication.getCredentials().toString());
BindAuthenticator bindAuth = new BindAuthenticator(ldapContextSource);
FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(
"", "(uid={0})",
ldapContextSource);
try {
bindAuth.setUserSearch(userSearch);
bindAuth.afterPropertiesSet();
} catch (Exception ex) {
java.util.logging.Logger.getLogger(CustomAuthenticationManager.class.getName()).log(Level.SEVERE, null, ex);
}
provider = new LdapAuthenticationProvider(bindAuth);
provider.setUserDetailsContextMapper(new UserDetailsContextMapper() {
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> clctn) {
Optional<User> isUser = userRepository.findOneWithAuthoritiesByLogin(username);
final User user = isUser.get();
Set<Authority> userAuthorities = user.getAuthorities();
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (Authority a : userAuthorities) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(
a.getName());
grantedAuthorities.add(grantedAuthority);
}
return new org.springframework.security.core.userdetails.User(
username, "1", grantedAuthorities);
}
@Override
public void mapUserToContext(UserDetails ud, DirContextAdapter dca) {
}
});
return provider.authenticate(authentication);
}
}
SecurityUtils :
public final class SecurityUtils {
private SecurityUtils() {
}
/**
* Get the login of the current user.
*
* @return the login of the current user.
*/
public static Optional<String> getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication()));
}
private static String extractPrincipal(Authentication authentication) {
if (authentication == null) {
return null;
} else if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
return springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
return (String) authentication.getPrincipal();
}else if (authentication.getPrincipal() instanceof LdapUserDetails) {
LdapUserDetails ldapUser = (LdapUserDetails) authentication.getPrincipal();
return ldapUser.getUsername();
}
return null;
}
/**
* Get the JWT of the current user.
*
* @return the JWT of the current user.
*/
public static Optional<String> getCurrentUserJWT() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(securityContext.getAuthentication())
.filter(authentication -> authentication.getCredentials() instanceof String)
.map(authentication -> (String) authentication.getCredentials());
}
/**
* Check if a user is authenticated.
*
* @return true if the user is authenticated, false otherwise.
*/
public static boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authentication != null &&
getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals);
}
/**
* If the current user has a specific authority (security role).
* <p>
* The name of this method comes from the {@code isUserInRole()} method in the Servlet API.
*
* @param authority the authority to check.
* @return true if the current user has the authority, false otherwise.
*/
public static boolean isCurrentUserInRole(String authority) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authentication != null &&
getAuthorities(authentication).anyMatch(authority::equals);
}
private static Stream<String> getAuthorities(Authentication authentication) {
return authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority);
}
}
Подскажите, пожалуйста, или посоветуйте в какую сторону смотреть, чтобы исправить подобную ошибку, спасибо!