【问题标题】:JHipster Using LDAP AuthentificationJHipster 使用 LDAP 认证
【发布时间】:2017-10-19 18:00:45
【问题描述】:

我几周前就开始使用 JHipster,从现在开始一切都找到了。我想同时拥有一个 LDAP 身份验证和 JHipster 的默认身份验证。

我关注了这个https://jhipster.github.io/tips/016_tip_ldap_authentication.html,但它没有按计划工作。 实际上我的配置很好地连接到我的 LDAP 服务器,我通过查看日志知道登录搜索到 LDAP 服务器并比较密码。

问题是登录失败并出现错误:

UT005023: Exception handling request to /api/authentication

org.springframework.security.core.userdetails.UsernameNotFoundException: User nseys was not found in the database
    at com.mycompany.myapp.security.PersistentTokenRememberMeServices.lambda$onLoginSuccess$1(PersistentTokenRememberMeServices.java:116)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at com.mycompany.myapp.security.PersistentTokenRememberMeServices.onLoginSuccess(PersistentTokenRememberMeServices.java:116)
    at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.loginSuccess(AbstractRememberMeServices.java:294)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    ...

问题是我希望 JHipster 在数据库中不存在用户时自动在数据库中创建用户并使用参数映射(但仅当它是 LDAP 用户时),如果已经完成则只需连接。

我也搜索了 Spring-security 解决方案,但实现与 JHipster 创建的初始文件相距太远,我不想破坏这一切。

【问题讨论】:

    标签: java spring-security ldap jhipster


    【解决方案1】:

    好吧,我尝试了一些可行的方法,我不知道我是否应该这样做,但由于我对此一无所知,而且没有很多文档记录,除非我发现我会坚持使用该解决方案更好的解决方案。

    // PersistentTokenRememberMeServices.java
    
    protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication
        successfulAuthentication) {
    
        String login = successfulAuthentication.getName();
    
        log.debug("Creating new persistent login for user {}", login);
    
        PersistentToken t = new PersistentToken();
        t.setSeries(RandomUtil.generateSeriesData());
        t.setTokenValue(RandomUtil.generateTokenData());
        t.setTokenDate(LocalDate.now());
        t.setIpAddress(request.getRemoteAddr());
        t.setUserAgent(request.getHeader("User-Agent"));
    
        PersistentToken token = userRepository.findOneByLogin(login).map(u -> {
            t.setUser(u);
            return t;
        }).orElse(null);
    
        if (token == null) {
            if (successfulAuthentication.getPrincipal() instanceof LdapUserDetails) {
                User ldapUser = new User();
                ldapUser.setLogin(login);
                ldapUser.setPassword(RandomStringUtils.random(60)); // We use LDAP password, but the password need to be set
                ldapUser.setActivated(true);
    
                CustomLdapUserDetails customLdapUserDetails = (CustomLdapUserDetails) successfulAuthentication.getPrincipal();
                ldapUser.setEmail(customLdapUserDetails.getEmail());
                ldapUser.setFirstName(customLdapUserDetails.getFirstName());
                ldapUser.setLastName(customLdapUserDetails.getLastName());
    
                Set<Authority> authorities = new HashSet<>();
                authorities.add(this.authorityRepository.findOneByName("ROLE_USER"));
                ldapUser.setAuthorities(authorities);
                ldapUser.setLangKey("fr");
    
                userRepository.save(ldapUser);
                t.setUser(ldapUser);
                token = t;
            } else {
                throw new UsernameNotFoundException("User " + login + " was not found in the database");
            }
        }
        ...
    }
    

    我添加了一个 contextMapper 来获取 LDAP 服务器中的属性

    // SecurityConfiguration.java
    @Bean
    public UserDetailsContextMapper userDetailsContextMapper() {
        return new LdapUserDetailsMapper() {
            @Override
            public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
                UserDetails details = super.mapUserFromContext(ctx, username, authorities);
                return new CustomLdapUserDetails((LdapUserDetails) details, ctx);
            }
        };
    }
    
    @Inject
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(applicationProperties.getLdap().getUrl());
        contextSource.setBase(applicationProperties.getLdap().getBase());
        contextSource.setUserDn(applicationProperties.getLdap().getUserDn());
        contextSource.setPassword(applicationProperties.getLdap().getPassword());
        contextSource.afterPropertiesSet(); //needed otherwise you will have a NullPointerException in spring
    
        auth.ldapAuthentication()
            .userDetailsContextMapper(userDetailsContextMapper())
            .userSearchBase(applicationProperties.getLdap().getSearchBase()) //don't add the base
            .userSearchFilter(applicationProperties.getLdap().getSearchFilter())
            .contextSource(contextSource)
        ;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-20
      • 1970-01-01
      • 2012-10-09
      • 2013-01-26
      • 2011-11-17
      • 1970-01-01
      • 2011-04-19
      • 2016-08-11
      • 1970-01-01
      相关资源
      最近更新 更多