使用springboot的Restful LDAP身份验证服务

时间:2019-08-31 07:15:44

标签: spring-boot ldap restful-authentication spring-security-ldap

我正在编写一个程序,该程序可以验证通过HTTP POST发送的用户名和密码,并针对ldap进行验证,并将响应发送回用户(无论验证是否成功)。

我的Websecurity配置器实现

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.LdapShaPasswordEncoder;

import org.springframework.boot.autoconfigure.security.SecurityProperties;

@Configuration
@Order(SecurityProperties.IGNORED_ORDER)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
        http.csrf().disable();

    }

    @SuppressWarnings("deprecation")
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userDnPatterns("uid={0},ou=people")
                .groupSearchBase("ou=groups")
                .contextSource()
                    .url("ldap://localhost:8389/dc=springframework,dc=org")
                    .and()
                .passwordCompare()
                    .passwordEncoder(new LdapShaPasswordEncoder())
                    .passwordAttribute("userPassword");
    }

}

我的test-server.ldif

dn: dc=springframework,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: springframework

dn: ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=subgroups,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: subgroups

dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people

dn: ou=space cadets,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: space cadets

dn: ou=\"quoted people\",dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: "quoted people"

dn: ou=otherpeople,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: otherpeople

dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben Alex
sn: Alex
uid: ben
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=

dn: uid=bob,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Bob Hamilton
sn: Hamilton
uid: bob
userPassword: bobspassword
.
.

我也在application.properties中定义了这个。 spring.ldap.embedded.ldif = classpath:test-server.ldif

我正在尝试发布邮递员的数据,但我收到403响应的任何值。

enter image description here

我不知道为什么会给出403。 谁能理解我在做什么错。谢谢。

下面是更新的安全日志:

  

2019-09-03 10:11:56.942调试9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置1   在10个附加过滤器链中;触发过滤器:   'WebAsyncManagerIntegrationFilter'2019-09-03 10:11:56.944调试9040   -[nio-8080-exec-2] o.s.security.web.FilterChainProxy:/ rest / hello在其他过滤器链中的10中的位置2;射击   筛选器:'SecurityContextPersistenceFilter'2019-09-03 10:11:56.944   调试9040-[nio-8080-exec-2]   w.c.HttpSessionSecurityContextRepository:当前没有HttpSession   存在2019-09-03 10:11:56.945 DEBUG 9040 --- [nio-8080-exec-2]   w.c.HttpSessionSecurityContextRepository:没有SecurityContext是   可从HttpSession获得:null。将创建一个新的。   2019-09-03 10:11:56.947 DEBUG 9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置3   在10个附加过滤器链中;触发过滤器:“ HeaderWriterFilter”   2019-09-03 10:11:56.948调试9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置4   在10个附加过滤器链中;触发过滤器:“ LogoutFilter”   2019-09-03 10:11:56.948调试9040 --- [nio-8080-exec-2]   o.s.s.web.util.matcher.OrRequestMatcher:尝试使用Ant进行匹配   [pattern ='/ logout',GET] 2019-09-03 10:11:56.949 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher:正在检查   请求匹配项:'/ rest / hello';反对'/ logout'2019-09-03   10:11:56.949 DEBUG 9040 --- [nio-8080-exec-2]   o.s.s.web.util.matcher.OrRequestMatcher:尝试使用Ant进行匹配   [pattern ='/ logout',POST] 2019-09-03 10:11:56.949 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher:请求   'GET / rest / hello'与'POST / logout'不匹配2019-09-03 10:11:56.949   调试9040-[nio-8080-exec-2]   o.s.s.web.util.matcher.OrRequestMatcher:尝试使用Ant进行匹配   [pattern ='/ logout',PUT] 2019-09-03 10:11:56.950 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher:请求   'GET / rest / hello'与'PUT / logout'不匹配2019-09-03 10:11:56.950   调试9040-[nio-8080-exec-2]   o.s.s.web.util.matcher.OrRequestMatcher:尝试使用Ant进行匹配   [pattern ='/ logout',DELETE] 2019-09-03 10:11:56.950 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher:请求   'GET / rest / hello'与'DELETE / logout'不匹配2019-09-03   10:11:56.950 DEBUG 9040 --- [nio-8080-exec-2]   o.s.s.web.util.matcher.OrRequestMatcher:找不到匹配项2019-09-03   10:11:56.951 DEBUG 9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置5   在10个附加过滤器链中;触发过滤器:   'RequestCacheAwareFilter'2019-09-03 10:11:56.951 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache:已保存   请求不匹配2019-09-03 10:11:56.951 DEBUG 9040 ---   [nio-8080-exec-2] o.s.security.web.FilterChainProxy:   / rest / hello在其他过滤器链中的10的位置6;射击   筛选器:'SecurityContextHolderAwareRequestFilter'2019-09-03   10:11:56.953 DEBUG 9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置7   在10个附加过滤器链中;触发过滤器:   'AnonymousAuthenticationFilter'2019-09-03 10:11:56.958 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter:已填充   具有匿名令牌的SecurityContextHolder:   'org.springframework.security.authentication.AnonymousAuthenticationToken@938ad544:   委托人:anonymousUser;凭证:[受保护];已验证:   真正;细节:   org.springframework.security.web.authentication.WebAuthenticationDetails@b364:   RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId:null;已授予   单位:ROLE_ANONYMOUS'2019-09-03 10:11:56.958 DEBUG 9040 ---   [nio-8080-exec-2] o.s.security.web.FilterChainProxy:   / rest / hello在附加过滤器链中的10的位置8处;射击   过滤器:'SessionManagementFilter'2019-09-03 10:11:56.958 DEBUG 9040   --- [nio-8080-exec-2] o.s.s.w.session.SessionManagementFilter:请求的会话ID 84F3D9D1165FFEE7008EDB2FA99B0D88无效。   2019-09-03 10:11:56.958调试9040 --- [nio-8080-exec-2]   o.s.security.web.FilterChainProxy:/ rest / hello在位置9   在10个附加过滤器链中;触发过滤器:   'ExceptionTranslationFilter'2019-09-03 10:11:56.959调试9040 ---   [nio-8080-exec-2] o.s.security.web.FilterChainProxy:   / rest / hello在其他过滤器链中位于10的10位置;射击   过滤器:'FilterSecurityInterceptor'2019-09-03 10:11:56.960 DEBUG 9040   --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor:安全对象:FilterInvocation:URL:/ rest / hello;属性:   [认证] 2019-09-03 10:11:56.960 DEBUG 9040 ---   [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor:   先前已认证:   org.springframework.security.authentication.AnonymousAuthenticationToken@938ad544:   委托人:anonymousUser;凭证:[受保护];已验证:   真正;细节:   org.springframework.security.web.authentication.WebAuthenticationDetails@b364:   RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId:null;已授予   单位:ROLE_ANONYMOUS 2019-09-03 10:11:56.972 DEBUG 9040-   [nio-8080-exec-2] o.s.s.access.vote.AffirmativeBased:选民:   org.springframework.security.web.access.expression.WebExpressionVoter@136951e,   返回:-1 2019-09-03 10:11:56.983 DEBUG 9040 --- [nio-8080-exec-2]   o.s.s.w.a.ExceptionTranslationFilter:访问被拒绝(用户为   匿名);重定向到身份验证入口点

     

org.springframework.security.access.AccessDeniedException:访问为   被拒绝           在org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)   〜[spring-security-core-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)上   〜[spring-security-core-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)   〜[spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)   〜[spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)   〜[spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)   [spring-web-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)处   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)   [spring-web-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]           在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)   [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]           在org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)   [spring-web-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]

1 个答案:

答案 0 :(得分:0)

没有任何日志和可能更多的代码,就不可能提供明确的答案。但我有一些提示:

  • 样本凭据与您显示的样本ldif不匹配。也许有错误?

  • 似乎您正在使用自己的入口点。目前尚不清楚它应该如何工作,但是将带有凭据的JSON正文发布到看似安全的应用程序URL似乎并不正确。这可能导致将凭据发送到不应接收敏感信息的端点。也许您最好使用标准的身份验证机制

  • 密码比较不像使用LDAP绑定身份验证那样安全和灵活。它仅支持有限的密码哈希算法,这些算法不再被认为是安全的,并且在盐分密码的情况下,需要从LDAP条目中检索密码。 LDAP绑定支持LDAP服务器支持的任何哈希算法,并且现有密码永远不需要离开LDAP服务器

也许解决这些问题已经有助于解决潜在的问题。否则,添加RESTAuthenticationEntryPoint的代码并记录到该问题。