Как передать данные GenericFilterBean в WebSecurityConfigurerAdapter в Spring Boot? - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь перенаправить http на https в моем весеннем загрузочном приложении, используя:

http.requiresChannel().anyRequest().requiresSecure();

Но я получаю ERR_TOO_MANY_REDIRECTS.Причина этого заключается в том, что балансировщик нагрузки преобразует все https в http и направляет http на порт 8082, поэтому приложение никогда не видит https.

Я попытался исправить это, добавив isSecure перед перенаправлением http на https, например, в моей конфигурации:

public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
        //variables
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/css/**", "/js/**", "/admin/**")
                .permitAll().anyRequest().authenticated().and()
                .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
                .formLogin().loginPage("/login").permitAll().and()
                .logout().logoutSuccessUrl("/");

        //hsts
        http.headers().httpStrictTransportSecurity()
        .includeSubDomains(true).maxAgeInSeconds(31536000); 

        http.addFilterBefore(new IsSecureFilter(), ChannelProcessingFilter.class);

        //https compulsion
        if(!isSecureFilter.isSecure()) {
                http.requiresChannel().anyRequest().requiresSecure();
        }           
    }
       //rest of the code
}

Я пытаюсь использовать HttpServletRequestWrapper, чтобы я мог повторно использовать isSecure вWebSecurityConfiguration выше через IsSecureFilter, который я создал ниже, чтобы предотвратить бесконечные перенаправления:

public class RequestWrapper extends HttpServletRequestWrapper {
    private boolean isSecure;

    public RequestWrapper(HttpServletRequest request) throws IOException
    {
        //So that other request method behave just like before
        super(request);
        this.isSecure = request.isSecure();       
    }

    //Use this method to read the request isSecure N times
    public boolean isSecure() {
        return this.isSecure;
    }  
}

Ниже приведен фильтр, который я пытаюсь внедрить в WebSecurityConfiguration, чтобы использовать его значение isSecure выше:

@Component
public class IsSecureFilter extends GenericFilterBean {

    private boolean isSecure;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = new RequestWrapper((HttpServletRequest) request);

        this.isSecure = req.isSecure();

        chain.doFilter(req, response);
    }

    public boolean isSecure() {
        return this.isSecure;
    }
}

Таким образом, выполнение вышеуказанного кода и помещение example.com/login в браузер перенаправляет на https://example.com/login, но я все еще получаю ERR_TOO_MANY_REDIRECTS.Я не могу понять, что я делаю не так?Мои первые мысли:

  • Могу ли я внедрить IsSecureFilter в WebSecurityConfiguration для получения isSecure?

  • Правильно ли я добавляю фильтр IsSecureFilterк конфигурации.

  • Правильно ли определено отношение фильтра оболочки?

РЕДАКТИРОВАТЬ

1) Я изменил http.addFilterAfter(new isSecureFilter(), ChannelProcessingFilter.class); на http.addFilterAfter(isSecureFilter, ChannelProcessingFilter.class);, все еще без эффекта.

2) Я пытался изменить http.addFilterBefore(isSecureFilter, ChannelProcessingFilter.class); на http.addFilterAfter(isSecureFilter, ChannelProcessingFilter.class);, но это все еще неизменить что-либо.

1 Ответ

0 голосов
/ 15 февраля 2019

Вот решение для решения этой проблемы.На основании исследования, поскольку 8080 и 8082 используются для идентификации HTTP-трафика и HTTPS-трафика, добавляется некоторый код для проверки номера порта вместо «isSecure», чтобы решить, следует ли перенаправить HTTP-запрос или нет.Код выглядит следующим образом:

public class IsSecureFilter extends GenericFilterBean {

private boolean isSecure;
private int port;

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = new RequestWrapper((HttpServletRequest) request);
    HttpServletResponse res = (HttpServletResponse) response;
    this.isSecure = req.isSecure();
    this.port = req.getLocalPort();


    System.out.println("[DEBUG] : isSecure FILTER :: " + isSecure);
    System.out.println("[DEBUG] : port FILTER :: " + port);
    System.out.println("[DEBUG] : URL :: " + req.getRequestURL());
    String url = req.getRequestURL().toString().toLowerCase();
    if(url.endsWith("/login") && url.startsWith("http:") && port == 8080){
        url = url.replace("http:", "https:");
        String queries = req.getQueryString();
        if (queries == null) {
            queries = "";
        } else {
            queries = "?" + queries;
        }
        url += queries;
        res.sendRedirect(url);
    }
    else {
        chain.doFilter(req, response);
    }
}

public boolean isSecure() {
    return this.isSecure;
}

public boolean setIsSecure(boolean isSecure) {
    return this.isSecure = isSecure;
}

public int getPort() {
    return port;
}

public void setPort(int port) {
    this.port = port;
}

}

и удалите http.requiresChannel (). AnyRequest (). RequireSecure () в классе WebSecurityConfiguration.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...