[英]API Key based authentication for a single endpoint
在我的 Spring Boot 应用程序中,我需要两种类型的身份验证机制。 对于文件上传端点,它需要基于 api-key 的身份验证,而对于其他端点,它需要基于用户名密码的身份验证。 以前,只有基于用户名密码的身份验证,如下所示。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
//@Slf4j
/**
* This class is used to setup security.
*
*
*
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private CustomAuthenticationProvider customAuthProvider;
/**
* This method to configure HTTP Security.
*
* @param http
* - HttpSecurity
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.info("Entered in the actuator security cofigure method");
http.csrf().disable().authorizeRequests().antMatchers("/actuator/*").permitAll().anyRequest()
.authenticated().and().httpBasic();
}
// Ignore basic auth for WSDL URL
// Ignore basic auth for SWAGGER
/**
* This method to configure web security.
*
* @param web
* - WebSecurity
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/**/*.wsdl").antMatchers("/**/*.wsdl$*")
.antMatchers("/v2/api-docs");
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}
/**
* This method to configure Authentication Manager Builder.
*
* @param auth
* - AuthenticationManagerBuilder
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
}
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
}
为了支持基于 api-key 的身份验证,我更改了此代码。 经历了以下线程并相应地实施。 使用 API 密钥和秘密保护 Spring Boot API
Spring Security:多个 HTTP 配置不起作用
执行:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
// @Slf4j
/**
* This class is used to setup security.
*
*
*/
@EnableWebSecurity
public class MultiSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(MultiSecurityConfig.class);
/** This method to configure HTTP Security. */
@Configuration
@Order(2)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Value("${http.auth-token-header-name}")
private String principalRequestHeader;
@Value("${http.auth-token}")
private String principalRequestValue;
protected void configure(HttpSecurity http) 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;
}
});
http.csrf().disable().antMatcher("/**/file").authorizeRequests().anyRequest().authenticated();
}
}
@Order(1)
@Configuration
public static class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private CustomAuthenticationProvider customAuthProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.info("Entered in the actuator security cofigure method");
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/actuator/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
// Ignore basic auth for WSDL URL
// Ignore basic auth for SWAGGER
/**
* This method to configure web security.
*
* @param web - WebSecurity
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/**/*.wsdl")
.antMatchers("/**/*.wsdl$*")
.antMatchers("/v2/api-docs");
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}
/**
* This method to configure Authentication Manager Builder.
*
* @param auth - AuthenticationManagerBuilder
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
}
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
}
}
但是当我使用“/file”端点将文件上传到服务器时,似乎基于 api 密钥的身份验证没有捕获它。 它进入基于登录的身份验证并返回未经授权的响应。
有什么帮助解决吗?
对于@Order
注释,较低的值具有较高的优先级。 意味着您的用户名/密码身份验证首先触发。 并且说身份验证有一个.anyRequest()
语句,导致它捕获所有请求。
排序较低的配置应该捕获特定的端点,而最高的是默认配置。 在您的情况下,这意味着 API 端点应该是@Order(1)
并且默认应该是@Order
在不相关的注释上,我认为您应该从封装类中删除extends WebSecurityConfigurerAdapter
并将@Configuration
删除,因为它包含 spring 需要在启动时获取的配置属性,但不是WebSecurityConfigurerAdapter
的实例,因为您的子类现在是
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.