Spring + GraphQL - необязательная авторизация

В настоящее время я использую Spring Boot Starter и GraphQL Java Tools, чтобы использовать GraphQL в моем приложении Spring . Он хорошо работает вместе с моим фильтром авторизации, если я авторизую конечную точку graphql. Теперь я хотел бы открыть для публики определенные мутации или запросы (таким образом, авторизация не требуется), и именно здесь я спотыкаюсь. Как я могу открыть конечную точку graphql, но по-прежнему иметь возможность использовать аннотацию @PreAuthorize безопасности Spring для авторизации на уровне метода? Другими словами: возможна ли «необязательная» авторизация на конечной точке?

Это моя конфигурация:

@Override
protected void configure(HttpSecurity http) throws Exception {
    log.debug("configureHttpSecurity");

    // Only authorize the request if it is NOT in the permitAllEndpoints AND matches API_ROOT_URL OR
    // MESSAGING_ROOT_URL
    List<RequestMatcher> requestMatchers = new ArrayList<>();
    requestMatchers.add(new SkipPathRequestMatcher(permitAllEndpointList, API_ROOT_URL));
    requestMatchers.add(new AntPathRequestMatcher(MESSAGING_ROOT_URL));
    OrRequestMatcher apiMatcher = new OrRequestMatcher(requestMatchers);

    http.csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeRequests()
                .antMatchers(permitAllEndpointList.toArray(new String[0]))
                .permitAll()
            .and()
                .authorizeRequests()
                .antMatchers(API_ROOT_URL, MESSAGING_ROOT_URL)
                .authenticated()
            .and()
                .addFilterBefore(new CustomCorsFilter(),
                        UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new AuthenticationFilter(authenticationManager()),
                        UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new AuthorizationFilter(apiMatcher),
                        UsernamePasswordAuthenticationFilter.class);
}

apiMatcher предназначен для открытия определенных конечных точек REST. Это мой AuthorizationFilter:

@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
                                            HttpServletResponse httpServletResponse)
        throws AuthenticationException, IOException, ServletException {
    try {
        String authorization = httpServletRequest.getHeader("Authorization");
        if (authorization != null && authorization.startsWith("Bearer ")) {
            return getAuthentication(authorization.replace("Bearer ", ""));
        }
    } catch (ExecutionException e) {
        httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN,"The provided token was either not valid or is already expired!");
        return null;
    } catch (IOException | InterruptedException e) {
        httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"There was a problem verifying the supplied token!");
        return null;
    }
    httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Unauthorized");
    return null;
}

Если я не отправлю сообщение об ошибке в конце attemptAuthentication, я смогу получить доступ к конечным точкам REST, которые не должны быть открыты. Кроме того, если я просто разрешаю конечную точку GraphQL, тогда авторизация не произойдет, и, следовательно, каждый @PreAuthorize будет терпеть неудачу, даже если я предоставлю действительный JWT. Возможно, мой подход к этому уже неверен. Если это так, дайте мне знать.


person puelo    schedule 26.05.2018    source источник


Ответы (1)


Я решил эту проблему, используя две конфигурации безопасности. Один для моего REST api с принудительной аутентификацией / авторизацией. Другой имеет дополнительный фильтр авторизации, который использует токен, только если он присутствует. Единственным недостатком сейчас является то, что все запросы и изменения по умолчанию открыты для публики и требуют закрытия аннотации @PreAuthorize.

person puelo    schedule 10.06.2018