簡體   English   中英

JHipster ldap認證

[英]JHipster ldap Authentication

嘿,Overfloweens和JHipsters,我最近得出的結論是,我想嘗試將我的JHipster安全性與協議鏈接到ldap服務器,以驗證已經具有所有員工密碼和用戶名的工作目錄中的身份驗證。 但是,我想繼續使用JHipster的內置令牌系統,該系統使用Spring-mvc。 除了JHipster,我知道如何做ldap服務器,但是我不清楚如何修改SecurityConfiguration.java文件以實現這一點。 任何建議將不勝感激。

安全配置文件:

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 {
    }
}

默認身份驗證機制使用“ UserDetailsS​​ervice”實現,在您的項目中應將其稱為“ com.comcast.castit.security.UserDetailsS​​ervice”。

該代碼具有一個簡單的“ loadUserByUsername”,可根據用戶的登錄信息獲取該用戶並獲取其權限。

對於您的需求,您應該更改此部分->這不會影響應用程序的其余部分,這很好(Spring Security為此設計很好)

有一個關於將LDAP與Spring Security / Spring Boot結合使用的教程,您可以在這里查看: https : //spring.io/guides/gs/authenticating-ldap/

當然,如果我們有針對JHipster的特定文檔,那會更好,因此,如果您成功並有時間,將非常歡迎您提供反饋!

SecurityConfiguration.javaconfigureGlobal函數更改為:

@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憑據進行。

從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);
    }
}

如果您需要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);
        }
    });

為了使用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中,我更改了register方法以在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);
        }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM