Есть ли способ полностью удалить страницу учетных данных, предоставленную spring Security, и использовать пользовательский поставщик аутентификации для реализации CSRF?

#angular #spring #spring-boot #spring-security

#angular #spring #spring-boot #spring-security

Вопрос:

Я пытаюсь реализовать реализацию токена CSRF на основе Spring Security и Angular 4. Первоначальная аутентификация для моего приложения использует страницу единого входа организации. Сообщение, которое мы перенаправляем на домашнюю страницу приложения. Ниже приведена моя реализация WebSecurityConfigurerAdapter с использованием 2 уровней фильтров, 1 для проверки и добавления токена CSRF, другой — для целей внутренней аутентификации приложений для обеспечения безопасности на уровне метода с использованием @Secured.

 @Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfiguration.class);
          
    @Autowired
    private CustomAuthenticationProviderService authenticationProviderService;

    public static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";

    private static final String[] CSRF_IGNORE = { ""};

    private static final String CSRF_HEADER_NAME = "X-XSRF-TOKEN";

    @Component
    @Order(1)
    public class CustomCsrfFilter extends 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, CSRF_COOKIE_NAME);
                String token = csrf.getToken();

                if (cookie == null || token != null amp;amp; !token.equals(cookie.getValue())) {
                    cookie = new Cookie(CSRF_COOKIE_NAME, token);
                    cookie.setPath("/");
                    cookie.setHttpOnly(false);
                    response.addCookie(cookie);
                }
            }

            filterChain.doFilter(request, response);
        }
    }

    @Bean
    @Order(2)
    public FilterRegistrationBean createFilterRegistrationBean() {

        FilterRegistrationBean registration = new FilterRegistrationBean(new OncePerRequestFilter() {

            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                    FilterChain filterChain) throws ServletException, IOException {

                try {
                        // App method specific authentication code
                        return;
                    }

                } catch (AuthenticationException e) {
                    LOGGER.error("Authentication error", e);
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.sendRedirect("/error/unauthorized.html");
                    return;
                }

            }

     
            @Override
            protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
                String uri = request.getRequestURI();
                return uri.startsWith("/resources/") || uri.startsWith("/static/") || uri.startsWith("/css/")
                        || uri.startsWith("/images/") || uri.startsWith("/js/") || uri.startsWith("/api/tct/")
                        || uri.startsWith("/api/unit/unitConversion");
            }
        });

        return registration;
    }

    
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.httpBasic()
        .and().csrf() // csrf config starts here
                .ignoringAntMatchers(CSRF_IGNORE) // URI where CSRF check will not be applied
                .csrfTokenRepository(csrfTokenRepository()) // defines a repository where tokens are stored
                .and().addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class)
                ; // Csrf filter in
        // which we will add
        // the cookie

    }

    private CsrfTokenRepository csrfTokenRepository() {

        CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        tokenRepository.setCookiePath("/");

        return tokenRepository;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProviderService);
    }

}
  

вот мой код в Angular для встраивания токена CSRF:

поставщики модуля приложения

 {
      provide: HTTP_INTERCEPTORS,
      useClass: MyHttpInterceptor,
      multi: true
    }

custom interceptor to append cookies:

import { Injectable } from "@angular/core";
import { tap } from "rxjs/operators";
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from "@angular/common/http";
import { Observable } from "rxjs/Observable";

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
  constructor() { }
  //function which will be called for all http calls
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    let requestToForward = request;
    let token = getCookie("XSRF-TOKEN");
    if (token != null) {
      requestToForward = request.clone(
        { setHeaders: { 'XSRF-TOKEN': token } });
    }

    return next.handle(requestToForward);
  }
}

function getCookie(name: String) {
  const splitCookie = document.cookie.split(';');
  for (let i = 0; i < splitCookie.length; i  ) {

    const splitValue = splitCookie[i].split('=');
    if (splitValue[0] === name) {
      return splitValue[1];
    }
  }
  return '';
}
  

Итак, я получаю это всплывающее окно при нескольких POST-запросах имени пользователя и пароля. Поскольку я внедрил пользовательскую аутентификацию, я не полагаюсь на ввод, предоставленный в этой форме по умолчанию для моей проверки, и, по сути, просто нужно нажать «Войти», когда он появится, не предоставляя никаких подробностей. Я бы хотел удалить это всплывающее окно, поскольку оно действительно не имеет никакой цели быть там.

Заранее спасибо.

Комментарии:

1. внедрение пользовательской безопасности — плохая практика.

2. @Thomas Мне не нужна вся часть аутентификации / авторизации, но мне нужна только реализация CSRF. Я попытался отключить http Basic через appllication. yml от security.basic.enabled: false, но этого тоже не удалось достичь.

3. Если вы не можете отключить его, вы делаете это неправильно. Проверьте официальную документацию. Все это там.

4. @Thomas Я считаю, что это больше связано с пользовательской реализацией, связанной с версией spring security, которую я использую. Проект основан на Spring Boot 1.7, и, следовательно, обновление до одной из более новых версий приведет к сбою многих функций. Было бы очень полезно, если бы вы могли поделиться некоторыми ссылками на документацию для той же версии.

5. У меня нет никаких ссылок на документацию о чем-то таком старом. Удачи