Spring Boot Filter и базовая аутентификация не дают правильного ответа - PullRequest
0 голосов
/ 13 мая 2019

Я делаю базовую аутентификацию при весенней загрузке. Также у меня есть фильтр, который выполняет фильтрацию заголовка и выдает ошибку, если я не передам необходимые значения в заголовке. Аутентификация и фильтрация заголовков работают нормально, если реализованы отдельно. Но если мы реализуем оба, я получаю одинаковый ответ для обеих проверок (фильтра и базовой аутентификации). Я предполагаю, что ответ фильтра генерируется первым, а позже заменяется ответом аутентификации.

PS: используется ** в приведенном ниже коде, чтобы указать местонахождение проблемы. Любые эксперты, пожалуйста, совет. Спасибо


@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE+2000)
@WebFilter
public class ValidTenantFilter extends OncePerRequestFilter {

    @Autowired
    private ClientRepository clientRepository;

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        return Constant.TENANT_FILTER_URL_LIST.stream()
                .anyMatch(p -> pathMatcher.match(p, request.getServletPath()));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("Inside Tenant Checker filter for path {} with  method {} ",request.getServletPath(),request.getMethod());
        if(!this.isValidTenant(request)) {
        **  response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid "+ Constant.X_COMPANY_ID+" and/or "+Constant.X_OPERATOR_ID+ " are passed. Please validate the request."); **
        }
        else {
            filterChain.doFilter(request, response);
        }
    }

    private boolean isValidTenant(HttpServletRequest request) {
        // Getting company id and operator id from the header , earlier we were using the tenant id 
        String companyId = request.getHeader(Constant.X_COMPANY_ID);
        String operatorId=request.getHeader(Constant.X_OPERATOR_ID);
        if(StringUtils.isNotEmpty(companyId) && StringUtils.isAlphanumeric(companyId) 
            &&  StringUtils.isNotEmpty(operatorId) && StringUtils.isAlphanumeric(operatorId)) {

            Client client = clientRepository.findByIdAndOperatorId(companyId, operatorId);
            //Only active clients request are entertained. // PRODUCT FIX
            if(client!=null && client.getId()!=null && client.isActive()) {
                MDC.put(MDC_CLIENT_ID, client.getId().toString());
                TenantContext.setCurrentTenant(client.getId().toString());
                return true;
            }

        }
        return false;
    }

}

И ниже код для аутентификации:

@Configuration
@EnableWebSecurity
@Slf4j
public class SomeConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPointImpl authEntryPoint;

    @Autowired
    private ApplicationClients application;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .csrf().disable()
        .cors().disable();

        //http.requiresChannel().antMatchers("/*").requiresSecure();

        http.authorizeRequests()
      //  .antMatchers("/**").hasRole("ADMIN")
      //.antMatchers("/user").hasAnyRole("ADMIN")
        .anyRequest().authenticated()
        .and().httpBasic();

        http.headers().defaultsDisabled().cacheControl().and().contentTypeOptions()
        .and().frameOptions().deny().xssProtection().block(false)
        .and().httpStrictTransportSecurity().includeSubDomains(true).maxAgeInSeconds(31536000);

        // Use AuthenticationEntryPoint to authenticate user/password
        http.httpBasic().authenticationEntryPoint(authEntryPoint);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources",
                "/swagger-resources/configuration/**", "/swagger-ui.html", "/webjars/**");
    }

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

    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        log.info("Importing {} clients:", application.getClients().size());

        application.getClients().forEach(client -> {
            String encrytedPassword = this.passwordEncoder().encode(client.getPassword());
            manager.createUser(User.withUsername(client.getUsername()).password(encrytedPassword).roles(client.getRoles()).build());
            log.info("Imported client {}", client.toString());
        });

        return manager;
    }

}

Код для точки входа аутентификации:

@Component
public class AuthenticationEntryPointImpl extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
            throws IOException, ServletException {
                //This is invoked when a user tries to access a secured REST resource without supplying any credentials
                //We should just add a 401 Unauthorized response because there is no 'login page' to redirect to
            **  response.setContentType("application/json");
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getOutputStream().println("{\"status\": " + HttpServletResponse.SC_UNAUTHORIZED + ", \"message\": \"" + authEx.getMessage() + "\" }");**
    }

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

}

Получение ниже Ответа в POSTMAN: 1. Если я не передаю учетные данные почтальона, я получаю ответ ниже

{ «статус»: 401, «message»: «Для доступа к этому ресурсу требуется полная аутентификация» }

  1. Если я не передаю заголовки, в идеале я должен получить ответ ниже:

{ «отметка времени»: 1557753285553, «статус»: 403, «ошибка»: «Запрещено», "message": "Переданы неверные X-COMPANY-ID и / или X-OPERATOR-ID. Пожалуйста, подтвердите запрос.", "путь": "/ apa / invoices" }

Но вместо этого я получаю ошибку ниже:

  1. { «статус»: 401, «message»: «Для доступа к этому ресурсу требуется полная аутентификация» }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...