带有apiKey和用户名/密码身份验证的REST API

时间:2019-05-18 10:35:24

标签: spring spring-security spring-rest

我是Spring的初学者,我正在尝试构建一个REST API,并将其连接到React前端以学习这些技术。 为了保护该API的安全,我通过创建一个过滤器检查了特定的标头密钥(在这种情况下为API-KEY),并仅允许匹配正确api密钥值的请求,来在Spring Security中添加了apiKey机制。

我在安全配置中添加了此过滤器,该过滤器扩展了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()之类的方法在过滤器中定义一个顺序,但是我不知道如何在用例中设置它。 我还发现了这篇文章:How to config multiple level authentication for spring boot RESTful web service? 似乎有相同的要求,我尝试了提供的解决方案,但是身份验证不是动态的(它的身份验证过滤器仅使用字符串“ valid-user”,并且我需要通过存储在In-内存h2数据库。如何实现?

非常感谢您的回答,祝您有愉快的一天!

0 个答案:

没有答案