Как реализовать ядро ​​безопасности Grails Spring с реализацией аутентификации basi c, которая не отображает диалоговое окно входа в систему для запросов 401? - PullRequest
0 голосов
/ 05 августа 2020

У меня есть приложение Grails response с ядром безопасности Spring, использующее реализацию аутентификации basi c.

Диалог входа в систему для недействительных запросов Мой интерфейс реакции связан с приложением Grails. Все мои запросы к бэкенду (моему приложению grails) - это запросы на публикацию. Теперь мне просто нужен статус 401/403, НО НЕ диалоговое окно входа в систему для недопустимых запросов или неправильных запросов, как в POSTMAN . Из-за этой проблемы вся моя система не подходит, так как для каждого недействительного запроса появляется диалоговое окно входа в систему, как показано на рисунке.

Есть ли способ избежать этого диалогового окна входа и просто позволить интерфейсу обрабатывать ответ статуса ?

Версия Grails: 3.3.5 Версия ядра безопасности Spring: 3.2.3

Ответы [ 2 ]

1 голос
/ 06 августа 2020

При использовании basi c auth, то, что вызывает диалог входа в систему браузера, - это наличие WWW-Authenticate заголовка в ответе 401. Итак, ваша цель здесь - удалить это.

При настройке безопасности Spring по умолчанию причина отправки заголовков: BasicAuthenticationEntryPoint.

Поскольку здесь также отображается realm для пользователя, вот хуки в базовом конфигураторе c auth для замены точки входа (где BasicAuthenticationEntryPoint - значение по умолчанию, если не установлено).

Итак, вот пример с обычная пружинная защита для установки:

@Configuration
@EnableWebSecurity
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                    .disable()
                .httpBasic()
                    .authenticationEntryPoint(new BasicAuthenticationEntryPointWithoutWWWAuthenticate())
    }
}

// See org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
class BasicAuthenticationEntryPointWithoutWWWAuthenticate implements AuthenticationEntryPoint {
    void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        // XXX don't set the header, that triggers the browser to show the login form
        // response.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");
        response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
    }
}
0 голосов
/ 08 августа 2020

Мне нужен был быстрый и простой способ решить эту проблему с помощью моей существующей реализации без добавления spring-security-rest. Итак, я последовал ответу @cfrick, чтобы удалить заголовок «WWW-Authenticate» в своем ответе. Вот шаги, которые я предпринял:

  1. Создайте настраиваемый фильтр пружины, который расширяет GenericFilterBean из spring, зарегистрируйте его, как описано здесь: spring-security-grails-do c
  2. Создайте настраиваемую оболочку ответа для изменения ответа внутри фильтра.
  3. В методе addHeader оболочки ответа установите все заголовки, кроме WWW-Authenticate.

Вот мой код фильтра:

class RemoveLoginPromptFilter extends GenericFilterBean{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException{
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse)response){
            @Override
            public void addHeader(String name, String value){
                if(!name.equalsIgnoreCase("www-authenticate")){
                    this.setHeader(name,value)
                }
            }
        }
        chain.doFilter(request,wrapper)
    }
}
...