Configurar la seguridad muelle de múltiples tipos de autenticación para la autenticación básica ingenio y JWT

Alexander Dunn:

Tengo una API que necesita ser asegurado de dos maneras diferentes:

1) El uso de JWT para todos de que no sea 1 URL de solicitud que debe ser asegurado con autenticación básica

2) Basic Auth en una única URL.

Tengo las configuraciones de seguridad de configuración para ambos JWT y autenticación básica. Mi problema es que cuando hago una petición a la URL autenticados Basic utilizando un nombre de usuario y una contraseña válidos, Me autentica y hace su trabajo de almacenar datos dentro de Cassandra con éxito.

entonces esperar a tener que generar un token para todas las demás URL de solicitud de VIA / api / login y añadirlo a la autorización: Portador {} simbólico de cabecera ..

Sin embargo, si ive sido autenticado mediante autenticación básica, puedo entonces acceder a la otra URL (protegido por JWT auth) sin ni siquiera tener una ficha en la solicitud.

Cuando tengo acceso a la dirección URL de JWT protegida sin necesidad de autenticación con autenticación básica, tengo que enviar el token en la cabecera y funciona como se esperaba ..

¿Debo esperar esto? Como creo que a pesar de que ive verifica a través de autenticación básica para un punto final, todavía tendría que enviar códigos en la solicitud de todos los demás criterios de valoración JWT protegidos ..

He encontrado esta respuesta: SpringBoot adaptador de autenticación múltiple

y también este artículo: https://docs.spring.io/spring-security/site/docs/4.2.x/reference/htmlsingle/#multiple-httpsecurity

y trató de implementar las soluciones, pero el problema como se explica todavía ocurre.

La clase de configuración de seguridad es el siguiente:

@Configuration
@EnableWebSecurity
public class SecurityHttpConfig extends WebSecurityConfigurerAdapter {

    @Configuration
    @Order(1)
    public static class BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter {

        @Value("${basic.auth.user}")
        private String basicAuthUsername;

        @Value("${basic.auth.password}")
        private String basicAuthPassword;

        @Value("${crashboxx.consume.endpoint}")
        private String crashBoxxConsumeEndpoint;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests().antMatchers("/v1/crash/consumeCrashBoxxEvent").hasRole("ADMIN").and()
                    .httpBasic().authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);// We don't need sessions to be created.
        }

        @Bean
        public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
            return new CustomBasicAuthenticationEntryPoint();
        }

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
            auth.inMemoryAuthentication().withUser(basicAuthUsername).password(encoder.encode(basicAuthPassword))
                    .roles("ADMIN");
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    @Configuration
    @Order(2)
    public static class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntryPoint unauthorizedHandler;

        @Autowired
        private JwtAuthenticationProvider jwtAuthenticationProvider;

        // Any endpoints that require no authorization should be added here..
        @Value("${api.login.endpoint}")
        private String loginEndpoint;

        @Autowired
        public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) {
            authenticationManagerBuilder.authenticationProvider(jwtAuthenticationProvider);
        }

        @Bean
        public JwtAuthenticationTokenFilter authenticationTokenFilterBean() {
            return new JwtAuthenticationTokenFilter();
        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity.csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated();

            httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
            httpSecurity.headers().cacheControl();
        }
    }

Con la clase BasicAuthEntryPoint:

public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    private static final Gson gson = new Gson();

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
            final AuthenticationException authException) throws IOException, ServletException {
        // Authentication failed, send error response.
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println(gson.toJson("HTTP Status 401 : " + authException.getMessage()));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("Realm");
        super.afterPropertiesSet();
    }

También los impl JWT:

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Value("${jwt.header}")
    private String tokenHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        final String requestHeader = request.getHeader(tokenHeader);
        // Ensure Auth Header contains 'Bearer'
        if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
            String authToken = requestHeader.substring(7);
            JwtAuthentication authentication = new JwtAuthentication(authToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        chain.doFilter(request, response);
    }

Espero que esto haya tenido sentido .. Si hay más preguntas por favor hágamelo saber, pero parece que no puede conseguir alrededor de éste.

He añadido el 'caso especial' primera que es la dirección URL de autenticación básica, pero todavía no hace ninguna diferencia.

Gracias

PraveenKumar Lalasangi:

Código que envió en la configuración de seguridad de @Order(1)

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests().antMatchers("/v1/crash/consumeCrashBoxxEvent").hasRole("ADMIN").and()
            .httpBasic().authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Si este es el código exacto que esté utilizando, entonces su @Order(2)configuración no será consultado. Será configuración muertos.
¡Dejame explicar!
http.authorizeRequests()== http.antMatcher("/**").authorizeRequests()

En su primera configuración está utilizando un comodín y el resultado de su configuración se

  • /v1/crash/consumeCrashBoxxEvent accesible si se ha autenticado el usuario y tiene función de administrador
  • Rest of URL's accesible si se autentica usuario

Déjame adivinar lo que está sucediendo!
1. usted está golpeando URL /v1/crash/consumeCrashBoxxEvento any URLse le pedirá para la autenticación básica.
2. Después de una autenticación exitosa se puede acceder a cualquier URL, porque usted es un usuario autenticado.

Sin embargo, si ive sido autenticado mediante autenticación básica, puedo entonces acceder a la otra URL (protegido por JWT auth) sin ni siquiera tener una ficha en la solicitud.

Porque como he dicho se puede acceder a cualquier URL porque eres un usuario autenticado

Cuando tengo acceso a la dirección URL de JWT protegida sin necesidad de autenticación con autenticación básica, tengo que enviar el token en la cabecera y funciona como se esperaba

Compruebe sin señal se puede acceder o no. Porque una vez que si inicia la sesión mediante la autenticación básica no hay cierre de sesión del lado del servidor (incluso si reinicia el servidor). Se puede lograr de cierre de sesión sólo si se cierra el navegador. Así lo prueba mediante el cierre y el inicio del navegador de nuevo. Y la prueba de que al no enviar token de JWT.
Garantizar también su solicitud alcanzar JwtAuthenticationTokenFilter, registros de depuración puesto a verificar.

Al igual que en su pregunta hay gran cantidad de abstracciones, es muy difícil predecir exactamente lo que está sucediendo a menos de poner un código completo.

Déjame saber en los comentarios si mis predicciones se desviaron de real.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=315649&siteId=1
Recomendado
Clasificación