REST API с аутентификацией apiKey и username / password - PullRequest
0 голосов
/ 18 мая 2019

Я новичок в Spring и пытаюсь создать REST API, подключенный к интерфейсу React, чтобы изучить эти технологии. Чтобы защитить этот API, я добавил механизм apiKey в Spring Security, создав фильтр, который проверяет определенный ключ заголовка (в данном случае API-KEY) и разрешает только те запросы, которые соответствуют правильному значению ключа api.

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

Я хотел бы, чтобы все запросы были перехвачены для проверки значения API-KEY, но я также хотел бы иметь анонимные и аутентифицированные части в моем приложении. Как я мог этого добиться? Я нашел некоторые элементы, такие как перехватчики, но, похоже, он доступен только для приложения spring-mvc.

Вот фильтр, который я использую:

public class ApiKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter {

    /**
     * The request header we want to check with our apiKey
     */
    private String principalRequestHeader;


    public ApiKeyAuthFilter(String principalRequestHeader) {
        this.principalRequestHeader = principalRequestHeader;
    }

    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        return request.getHeader(principalRequestHeader);
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        return "N/A";
    }
}

А вот мой конфиг безопасности:

@Configuration
@EnableWebSecurity
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * The header corresponding to our apiKey
     */
    @Value("${application.security.requestKey}")
    private String apiKeyHeader;

    /**
     * The api key value we want to test with the header value
     */
    @Value("${application.security.apiKey}")
    private String apiKeyValue;


    Logger logger = LoggerFactory.getLogger(ApiSecurityConfig.class);


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ApiKeyAuthFilter filter = new ApiKeyAuthFilter(this.apiKeyHeader);

        filter.setAuthenticationManager(new AuthenticationManager() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                final String principal = (String) authentication.getPrincipal();

                if (!apiKeyValue.equals(principal)) {
                    throw new BadCredentialsException("The API key was not found or doesn't match the correct value");
                }

                logger.info("Connexion autorisée");
                authentication.setAuthenticated(true);
                return authentication;
            }
        });

        http.cors().and().
                antMatcher("/api/**").
                csrf().disable().
                sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
                and().
                addFilter(filter).
                authorizeRequests().anyRequest().authenticated();
    }
}

Есть ли у вас какие-либо подсказки, чтобы настроить этот вид аутентификации? Я видел, что мы можем определить порядок в нашем фильтре с помощью методов, таких как addFilterAfter () или addFilterBefore (), но я не знаю, как настроить это с моим сценарием использования. Я также нашел этот пост: Как настроить многоуровневую аутентификацию для веб-службы RESTful с весенней загрузкой? к которым, похоже, предъявляются те же требования, я попробовал предоставленное решение, но аутентификация не является динамической (она использует только строку «valid-user» для фильтра аутентификации, и мне нужно пройти аутентификацию через мою сущность User, хранящуюся в Память h2. Как этого добиться?

Большое спасибо за ваши ответы и хорошего дня!

...