2014-11-21 4 views
1

Hey Overfloweens и JHipsters, Я недавно пришел к выводу, что хочу попытаться связать свою защиту JHipster с протоколом на сервере ldap, чтобы проверить подлинность в моем рабочем каталоге, в котором уже есть весь сотрудник пароли и имена пользователей. Тем не менее, я хочу продолжать использовать встроенную систему токенов JHipster, которая использует Spring-mvc. Я знаю, как сделать сервер ldap отдельно от JHipster, но я не знаю, как изменить файл SecurityConfiguration.java, чтобы сделать это реальностью. Любые советы были бы очень ценными.JHipster ldap Аутентификация

настройки безопасности файла:

package com.comcast.castit.config; 

import javax.inject.Inject; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.env.Environment; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.password.PasswordEncoder; 
import org.springframework.security.crypto.password.StandardPasswordEncoder; 
import org.springframework.security.web.authentication.RememberMeServices; 

import com.comcast.castit.security.AjaxAuthenticationFailureHandler; 
import com.comcast.castit.security.AjaxAuthenticationSuccessHandler; 
import com.comcast.castit.security.AjaxLogoutSuccessHandler; 
import com.comcast.castit.security.AuthoritiesConstants; 
import com.comcast.castit.security.Http401UnauthorizedEntryPoint; 

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Inject 
    private Environment env; 

    @Inject 
    private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler; 

    @Inject 
    private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler; 

    @Inject 
    private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler; 

    @Inject 
    private Http401UnauthorizedEntryPoint authenticationEntryPoint; 

    @Inject 
    private UserDetailsService userDetailsService; 

    @Inject 
    private RememberMeServices rememberMeServices; 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
    return new StandardPasswordEncoder(); 
    } 

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

    @Override 
    public void configure(WebSecurity web) throws Exception { 
    web.ignoring().antMatchers("/bower_components/**") 
     .antMatchers("/fonts/**").antMatchers("/images/**") 
     .antMatchers("/scripts/**").antMatchers("/styles/**") 
     .antMatchers("/views/**").antMatchers("/i18n/**") 
     .antMatchers("/swagger-ui/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http.exceptionHandling() 
     .authenticationEntryPoint(authenticationEntryPoint).and() 
     .rememberMe().rememberMeServices(rememberMeServices) 
     .key(env.getProperty("jhipster.security.rememberme.key")).and() 
     .formLogin().loginProcessingUrl("/app/authentication") 
     .successHandler(ajaxAuthenticationSuccessHandler) 
     .failureHandler(ajaxAuthenticationFailureHandler) 
     .usernameParameter("j_username") 
     .passwordParameter("j_password").permitAll().and().logout() 
     .logoutUrl("/app/logout") 
     .logoutSuccessHandler(ajaxLogoutSuccessHandler) 
     .deleteCookies("JSESSIONID").permitAll().and().csrf().disable() 
     .headers().frameOptions().disable().authorizeRequests() 
     .antMatchers("/app/rest/register").permitAll() 
     .antMatchers("/app/rest/activate").permitAll() 
     .antMatchers("/app/rest/authenticate").permitAll() 
     .antMatchers("/app/rest/logs/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/app/**").authenticated() 
     .antMatchers("/metrics/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/health/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/dump/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/shutdown/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/beans/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/info/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/autoconfig/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/env/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/api-docs/**") 
     .hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/protected/**").authenticated(); 

    } 

    @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 
    private static class GlobalSecurityConfiguration extends 
     GlobalMethodSecurityConfiguration { 
    } 
} 

ответ

2

Механизм аутентификации по умолчанию использует «UserDetailsService» реализации, следует назвать «com.comcast.castit.security.UserDetailsService» в вашем проекте.

Этот код имеет простое «loadUserByUsername», которое выбирает пользователя в соответствии с его логином и получает его полномочия.

Для ваших потребностей, вы должны изменить эту часть -> это не повлияет на остальную часть вашего приложения, которое хорошо (Spring Security хорошо разработан для этого)

Существует учебник по использованию LDAP с Spring Security/Spring Boot, вы можете проверить здесь: https://spring.io/guides/gs/authenticating-ldap/

Конечно, было бы лучше, если бы у нас была специальная документация для JHipster, поэтому, если вам удастся и у вас будет время, ваши отзывы будут наиболее желанными!

0

Удалить следующий фрагмент кода из SecurityConfig.java

@Override 
@Bean 
public AuthenticationManager authenticationManagerBean() throws Exception { 
return (AuthenticationManager) ldapAuthenticationManager; 
} 

, а затем создать LDAPAuthenticationManager класс

package com.digitronic.isda.security; 

import org.springframework.ldap.core.AuthenticationSource; 
import org.springframework.ldap.core.support.LdapContextSource; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.ldap.DefaultSpringSecurityContextSource; 
import org.springframework.security.ldap.authentication.BindAuthenticator; 
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider; 
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; 
import org.springframework.stereotype.Component; 

@Component("authenticationManagerBean") 
public class LDAPAuthenticationManager implements AuthenticationManager { 


    LdapAuthenticationProvider provider = null; 

    @Override 
    public Authentication authenticate(Authentication arg0) 
      throws AuthenticationException { 

     return provider.authenticate(arg0); 
    } 

    LDAPAuthenticationManager() { 

     DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
       "ldap://127.0.0.1:389"); 
     contextSource.setUserDn("test.com\\Administrator"); 
     contextSource.setCacheEnvironmentProperties(true); 
     try { 
      contextSource.afterPropertiesSet(); 
     } catch (Exception e) { 

      e.printStackTrace(); 
     } 
     contextSource.setPassword("asdasdasdjBj,K"); 

     LdapContextSource ldapSrc = new LdapContextSource(); 
     ldapSrc.setUrl("ldap://127.0.0.1:389"); 
     ldapSrc.setUserDn("test.com\\Administrator"); 
     ldapSrc.setPassword("asdasdasdjBj,K"); 
     ldapSrc.setAnonymousReadOnly(false); 
     ldapSrc.setCacheEnvironmentProperties(true); 

     try { 
      ldapSrc.afterPropertiesSet(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     ldapSrc.setAuthenticationSource(new AuthenticationSource() { 

      @Override 
      public String getPrincipal() { 
       // TODO Auto-generated method stub 
       return "test.com\\Administrator"; 
      } 

      @Override 
      public String getCredentials() { 
       // TODO Auto-generated method stub 
       return "asdasdasdjBj,K"; 
      } 
     }); 

     FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(
       "cn=Users,dc=digitronic,dc=lan", "(sAMAccountName={0})", 
       ldapSrc); 

     BindAuthenticator bindAuth = new BindAuthenticator(contextSource); 
     bindAuth.setUserSearch(userSearch); 
     provider = new LdapAuthenticationProvider(bindAuth); 
    } 
} 
1

Если вам нужен UserDetailsContextMapper (для власти) добавить:

provider.setUserDetailsContextMapper(new UserDetailsContextMapper() { 

     @Override 
     public void mapUserToContext(UserDetails user, DirContextAdapter ctx) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public UserDetails mapUserFromContext(DirContextOperations ctx, 
       String username, 
       Collection<? extends GrantedAuthority> authorities) { 

      User anwender = userRepository.findOneByAnwender(username); 

      Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(); 
      GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(
        "ROLE_ADMIN"); 
      grantedAuthorities.add(grantedAuthority); 

      return new org.springframework.security.core.userdetails.User(
        username, "1", grantedAuthorities); 
     } 
    }); 
2

SecurityConfiguration.java изменение configureGlobal:

@Inject 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    /*auth 
     .userDetailsService(userDetailsService) 
      .passwordEncoder(passwordEncoder());*/ 

    auth.ldapAuthentication() 
    .userSearchBase("ou=Users") 
    .userSearchFilter("(uid={0})") 
    .groupSearchBase("ou=Groups") 
    .groupSearchFilter("member={0}") 
    .contextSource() 
    .url("ldap://127.0.0.1:10389/o=myorganisation"); 
} 

Я прокомментировал предыдущий код. Затем ваше приложение будет проходить проверку подлинности с вашего сервера ldap. Он по-прежнему будет проверять базу данных для сведений о пользователе, и если пользователь не существует в таблице пользователей, у вас будут проблемы вроде: userRepository.findOneByLogin(login), который ищет пользователя в базе данных с использованием существующего имени пользователя.

Но аутентификация произойдет с вашими учетными данными ldap.

1

Чтобы поддерживать встроенную систему маркеров JHipster с LDAP, я использовал другой подход. Всякий раз, когда пользователь пытается войти в систему, я выполняю поиск его учетных данных на сервере LDAP, и в случае его существования в локальной базе данных с его атрибутами LDAP создается новый пользователь, а затем все функции работают нормально.

Следующий класс используется для получения контекста вашего LDAP-сервера и пользовательских атрибутов.

public class LDAPHelper { 

private static LDAPHelper instance = null; 

protected LDAPHelper() { 
    // Exists only to defeat instantiation 
} 

public static LDAPHelper getInstance() { 
    if (instance == null) { 
     instance = new LDAPHelper(); 
    } 
    return instance; 
} 

public boolean validateLogin(String username, String password) { 
    return (getLdapContext(username, password) != null); 
} 

private LdapContext getLdapContext(String username, String password) { 
    Hashtable<String, String> env = new Hashtable<String, String>(); 

    env.put(Context.INITIAL_CONTEXT_FACTORY, 
      "com.sun.jndi.ldap.LdapCtxFactory"); 
    env.put("com.sun.jndi.ldap.read.timeout", "120000"); 
    env.put(Context.SECURITY_AUTHENTICATION, "Simple"); 
    env.put(Context.SECURITY_PRINCIPAL, "VF-ROOT\\" + username); 
    env.put(Context.SECURITY_CREDENTIALS, password); 
    env.put(Context.PROVIDER_URL, "*ldap url*"); 
    System.out.println(username); 
    try { 
     return new InitialLdapContext(env, null); 
    } catch (NamingException e) { 
     return null; 
    } 
} 

public User getUserAttributes(String username, String password) 
     throws NamingException { ... } 

В AccountResource я изменил метод регистра для поиска пользователя на сервере LDAP, и, если пользователь существует, добавить его в локальную базу данных, если он еще не был добавлен. Вы вызываете этот метод перед входом в систему, чтобы убедиться, что только пользователи, которые находятся на сервере LDAP, могут войти в ваше приложение.

 @RequestMapping(value = "/register", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE, 
     MediaType.TEXT_PLAIN_VALUE }) 
@Timed 
public ResponseEntity<?> registerAccount(@Valid @RequestBody ManagedUserDTO managedUserDTO, 
     HttpServletRequest request) { 

    HttpHeaders textPlainHeaders = new HttpHeaders(); 
    textPlainHeaders.setContentType(MediaType.TEXT_PLAIN); 

    // user exists in LDAP server 
    if (LDAPHelper.getInstance().validateLogin(managedUserDTO.getLogin(), managedUserDTO.getPassword())) { 

     // user was already created in the local database 
     if (userRepository.findOneByLogin(managedUserDTO.getLogin().toLowerCase()).isPresent()) { 

      return new ResponseEntity<>("user exists in database", textPlainHeaders, HttpStatus.OK); 

     } else { 

      try { 
       User userAux = LDAPHelper.getInstance().getUserAttributes(managedUserDTO.getLogin(), managedUserDTO.getPassword());        

       User user = userService.createUserInformation(managedUserDTO.getLogin(), managedUserDTO.getPassword(), userAux.getFirstName(), 
         userAux.getLastName(), userAux.getEmail(), managedUserDTO.getLangKey());           

       } catch (NamingException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

       return new ResponseEntity<>("user created in database", textPlainHeaders, HttpStatus.OK); 
      } 
     } else { 
      return new ResponseEntity<>("user does not exist in ldap", textPlainHeaders, HttpStatus.UNAUTHORIZED); 
     } 
} 
Смежные вопросы