web-dev-qa-db-fra.com

Sécurisation de l'API Spring Boot avec clé API et secret

J'aimerais sécuriser l'API Spring Boot afin qu'elle ne soit accessible qu'aux clients disposant d'une clé et d'un secret d'API valides. Cependant, il n'y a pas d'authentification (connexion standard avec nom d'utilisateur et mot de passe) dans le programme car toutes les données sont anonymes. Tout ce que j'essaie de faire, c'est que toutes les demandes d'API ne peuvent être utilisées que pour des clients tiers spécifiques.

J'ai trouvé de nombreux articles sur la sécurisation de l'API Spring Boot avec l'authentification de l'utilisateur. Mais je n'ai pas besoin de l'authentification de l'utilisateur. Je pense simplement à fournir à mon client une clé et un secret d’API afin qu’il ait accès aux points finaux.

Pourriez-vous s'il vous plaît me suggérer comment puis-je atteindre cet objectif? Je vous remercie!

25
Vitalii Oleksiv

Créez un filtre qui saisit le ou les en-têtes que vous utilisez pour l'authentification.

import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

public class APIKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter {

    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";
    }

}

Configurez le filtre dans votre configuration Web Security.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

@Configuration
@EnableWebSecurity
@Order(1)
public class APISecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${yourapp.http.auth-token-header-name}")
    private String principalRequestHeader;

    @Value("${yourapp.http.auth-token}")
    private String principalRequestValue;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        APIKeyAuthFilter filter = new APIKeyAuthFilter(principalRequestHeader);
        filter.setAuthenticationManager(new AuthenticationManager() {

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String principal = (String) authentication.getPrincipal();
                if (!principalRequestValue.equals(principal))
                {
                    throw new BadCredentialsException("The API key was not found or not the expected value.");
                }
                authentication.setAuthenticated(true);
                return authentication;
            }
        });
        httpSecurity.
            antMatcher("/api/**").
            csrf().disable().
            sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
            and().addFilter(filter).authorizeRequests().anyRequest().authenticated();
    }

}
40
MarkOfHall