2014-11-21 282 views
1

嘿Overfloweens和JHipsters, 我最近得出結論,我想嘗試將我的JHipster安全協議連接到協議到ldap服務器,以驗證已在我的工作目錄中擁有所有員工的身份驗證密碼和用戶名。但是,我想繼續使用JHipster的使用Spring-mvc的內置令牌系統。我知道除了JHipster之外,如何做ldap服務器,但我不清楚如何修改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

默認的身份驗證機制使用「的UserDetailsS​​ervice」的實施,應該在您的項目稱爲「com.comcast.castit.security.UserDetailsS​​ervice」。

此代碼有一個簡單的「loadUserByUsername」,根據用戶的登錄信息獲取用戶並獲得他的權限。

爲了你的需求,你應該改變這一部分 - >這不會影響您的應用程序,這是很好的休息(春季安全性以及專爲)

有使用LDAP和春天有個教程安全/彈簧啓動,你可以在這裏查看:https://spring.io/guides/gs/authenticating-ldap/

當然,如果我們有一個JHipster的特定文檔會更好,所以如果你成功並有時間,你的反饋將是最受歡迎的!

0

刪除下面的代碼片段從SecurityConfig.java

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

,然後如果你需要一個的UserDetailsContextMapper(有關當局)創建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

補充一點:

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

In SecurityConfiguration.java change 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

爲了使用LDAP維護JHipster的內置令牌系統,我採取了不同的方法。 每當用戶嘗試登錄時,我都會在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); 
     } 
}