繁体   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