복붙노트

[REDIS] 나쁜 액티브 디렉토리의 LDAP 자격 증명과 세션 / 레디 스 직렬화 오류 봄 부팅

REDIS

나쁜 액티브 디렉토리의 LDAP 자격 증명과 세션 / 레디 스 직렬화 오류 봄 부팅

안녕 나는 봄과 자바에 새로운,이 튜토리얼 https://spring.io/guides/tutorials/spring-security-and-angular-js/에 설명 된대로 게이트웨이 인증 서버를 구현하기 위해 노력하고 있어요

나는 모든 가공을 얻었다 후 우리 회사의 LDAP 서버에 대한 인증을 구현하기 위해 노력했다. 나는 유효한 사용자 이름과 암호를 사용하는 경우 작동합니다. 나는 잘못된 자격 증명에게 응용 프로그램 오류를 사용하는 경우.

내가 정확한 오류가없는, 그래서 나는 직장에서 아니지만, 그것은 반환되는 LDAP 오류 (com.sun.jndi.ldap.LdapCtx라고)와 레디 스를 직렬화하기 위해 노력하고있다.

내 구성에서 실종 뭔가입니다. 에서 난 내가 직렬화를 / 포장 클래스를 확장하고 구현하는 방법을 찾고해야한다고 생각 읽을 수있다, 그러나 나는 봄 부팅이 작업을 수행 할 수있는 최소 침습적 방법의 확신이 누구인지.

어떤 도움도 대단히 감사합니다.

감사,

마이크 코왈 스키

PS 지금까지 동적 언어와 프레임 워크에서 주로 일하고있다 (자바 스크립트 / 노드, PHP / Laravel)

저는 여기에 보안 구성의 관련 부분입니다 생각입니다 :

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .formLogin()
      .defaultSuccessUrl("/")
      .loginPage("/login")
      .permitAll()
      .and()
      .logout()
      .logoutSuccessUrl("/logout")
      .permitAll();


    http
      .authorizeRequests()
        .antMatchers("/login").permitAll()
        .anyRequest().authenticated()
    .and()
      .csrf().csrfTokenRepository(csrfTokenRepository())
    .and()
      .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
  }

  @Override
   protected void configure(AuthenticationManagerBuilder authManagerBuilder)          throws Exception {
    authManagerBuilder
      .authenticationProvider(activeDirectoryLdapAuthenticationProvider())
        .userDetailsService(userDetailsService());
   }

   @Bean
   public AuthenticationManager authenticationManager() {
      return new ProviderManager(
        Arrays.asList(activeDirectoryLdapAuthenticationProvider())
      );
   }

   @Bean
   public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
  ActiveDirectoryLdapAuthenticationProvider provider = new     ActiveDirectoryLdapAuthenticationProvider(
    "XXX.XXX", "ldaps://XXX.XXX:636");
      provider.setConvertSubErrorCodesToExceptions(true);
      provider.setUseAuthenticationRequestCredentials(true);
      return provider;
   }

  private Filter csrfHeaderFilter() {
    return new OncePerRequestFilter() {
      @Override
      protected void doFilterInternal(
        HttpServletRequest request,
        HttpServletResponse response, 
        FilterChain filterChain
      ) throws ServletException, IOException 
      {
        CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
            .getName());
        if (csrf != null) {
          Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
          String token = csrf.getToken();
          if (cookie == null || token != null
              && !token.equals(cookie.getValue())) {
            cookie = new Cookie("XSRF-TOKEN", token);
            cookie.setPath("/");
            response.addCookie(cookie);
          }
        }
        filterChain.doFilter(request, response);
      }
    };
  }

  private CsrfTokenRepository csrfTokenRepository() {
    HttpSessionCsrfTokenRepository repository = new     HttpSessionCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    return repository;
  }

}

여기에 잘못된 자격 증명을 사용하여 오류의 일부는 다음과 같습니다

2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@44258b05
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 5 of 13 in additional filter chain; firing Filter: ''
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider
2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Processing authentication request for user: admin
2015-09-24 15:07:31.113 DEBUG 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Authentication for admin@countrycurtains.local failed:javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece]
2015-09-24 15:07:31.113  INFO 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Active Directory authentication failed: User was not found in directory
2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@28626d9a
2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2015-09-24 15:07:31.115 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/login?error'
2015-09-24 15:07:31.115 DEBUG 6552 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2015-09-24 15:07:31.139 DEBUG 6552 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2015-09-24 15:07:31.148 ERROR 6552 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
        at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:52)
        at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:146)
        at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:128)
        at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:85)
        at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:409)
        at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:331)
        at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:211)
        at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:141)
        at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:193)
        at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:169)
        at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:127)
        at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:68)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:67)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:34)
        at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:50)
        ... 40 common frames omitted
Caused by: java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441)
        at java.lang.Throwable.writeObject(Throwable.java:985)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
        at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:44)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:62)
        ... 42 common frames omitted

해결법

  1. ==============================

    1.나는이 문제에 대한 해결책을 알아 냈어. 나는 대답을 개선하기 위해 어떤 제안에 열려입니다.

    나는이 문제에 대한 해결책을 알아 냈어. 나는 대답을 개선하기 위해 어떤 제안에 열려입니다.

    나는 특별히 볼 필요로 솔루션은 완전하지 않습니다 내가 특정 사건을 처리하고 나머지에 SerializationException을 던질 수 있도록 직렬화가 실패 할 때 com.sun.jndi.ldap.LdapCtx라고 입력합니다. 하지만 일반적인 생각이 차단되어 사람에게 유용 할 수 있습니다 생각했다.

    잘못된 자격 증명을 날려보다는 페이지의 로그 (예 : 잘못된 사용자 이름 또는 잘못된 암호를) 응용 프로그램 수익률을 사용하는 자 할 때 :

    나는 RedisTemplate 봄 세션이 사용하는 대체 어떤 RedisConfiguration을 추가했습니다.

    import com.gateway.utils.LdapFailAwareRedisObjectSerializer;
    
    @Configuration
    public class RedisConfiguration {
    
      @Primary
      @Bean
      public RedisTemplate<String,ExpiringSession> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
    
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new LdapFailAwareRedisObjectSerializer());
    
        template.setConnectionFactory(connectionFactory);
        return template;
      }
    }
    

    다음 (여기에서 받고 있습니다 LdapFailAwareRedisObjectSerializer) RedisSerializer <개체>의 내 구현은

    public class LdapFailAwareRedisObjectSerializer implements RedisSerializer<Object> {
    
      private Converter<Object, byte[]> serializer = new SerializingConverter();
      private Converter<byte[], Object> deserializer = new DeserializingConverter();
    
      static final byte[] EMPTY_ARRAY = new byte[0];
    
      public Object deserialize(byte[] bytes) {
        if (isEmpty(bytes)) {
          return null;
        }
    
        try {
          return deserializer.convert(bytes);
        } catch (Exception ex) {
          throw new SerializationException("Cannot deserialize", ex);
        }
      }
    
      public byte[] serialize(Object object) {
        if (object == null) {
          return EMPTY_ARRAY;
        }
    
        try {
          return serializer.convert(object);
        } catch (Exception ex) {
          return EMPTY_ARRAY;
          //TODO add logic here to only return EMPTY_ARRAY for known conditions
          // else throw the SerializationException
          // throw new SerializationException("Cannot serialize", ex);
        }
      }
    
      private boolean isEmpty(byte[] data) {
        return (data == null || data.length == 0);
      }
    }
    
  2. ==============================

    2.이것은 단지의 클래스를 사용 후 나를 위해 좋은 일했다 org.springframework.core.serializer.support.DeserializingConverter 과 org.springframework.core.serializer.support.SerializingConverter

    이것은 단지의 클래스를 사용 후 나를 위해 좋은 일했다 org.springframework.core.serializer.support.DeserializingConverter 과 org.springframework.core.serializer.support.SerializingConverter

    /**
     * @author Meron Abraha 12/18/17
     */
    
    public class CustomRedisSerializer implements RedisSerializer<Object> {
    
    private Converter<Object, byte[]> serializer = new SerializingConverter();
    private Converter<byte[], Object> deserializer = new DeserializingConverter();
    
    static final byte[] EMPTY_ARRAY = new byte[0];
    
    public Object deserialize(byte[] bytes) {
        if (isEmpty(bytes)) {
            return null;
        }
    
        try {
            return deserializer.convert(bytes);
        } catch (Exception ex) {
            throw new SerializationException("Cannot deserialize", ex);
        }
    }
    
    public byte[] serialize(Object object) {
        if (object == null) {
            return EMPTY_ARRAY;
        }
    
        try {
            return serializer.convert(object);
        } catch (Exception ex) {
            return EMPTY_ARRAY;
    
        }
    }
    
    private boolean isEmpty(byte[] data) {
        return (data == null || data.length == 0);
    }
    }
    
  3. ==============================

    3.스프링이 객체를 직렬화하고는 레디 스에 저장하기 때문에 자바 객체는 직렬화 가능 인터페이스를 구현해야합니다 캐시합니다.

    스프링이 객체를 직렬화하고는 레디 스에 저장하기 때문에 자바 객체는 직렬화 가능 인터페이스를 구현해야합니다 캐시합니다.

    예를 들면 공용 클래스 스토어는 Serializable를 구현

    여기에 짧은 이야기는 당신이 당신의 클래스의 직렬화 가능 인터페이스를 구현할 수 있도록한다.

    나는이 도움이되기를 바랍니다. 행운을 빕니다.

  4. from https://stackoverflow.com/questions/32751094/spring-boot-with-session-redis-serialization-error-with-bad-active-directory-lda by cc-by-sa and MIT license