当前位置: 首页 > 知识库问答 >
问题:

针对单个终端节点的基于 API 密钥的身份验证

冀越
2023-03-14

在我的 Spring Boot 应用程序中,我需要两种类型的身份验证机制。对于文件上传终结点,它需要基于 api 密钥的身份验证,对于其他终结点,它需要基于用户名密码的身份验证。以前,只有基于用户名密码的身份验证,如下所示。

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密钥的身份验证,我修改了这段代码。通过以下线程并相应地实现。使用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”endpoint将文件上传到服务器时,似乎基于api密钥的身份验证无法捕获它。它转到基于登录名的身份验证,并返回未经授权的响应。

有什么能帮上忙的吗?

共有1个答案

黎阳冰
2023-03-14

对于@顺序选项,较低的值具有较高的优先级。这意味着您的用户名/密码身份验证首先触发。并且所述认证具有<code>。anyRequest()语句,该语句将捕获所有请求。

较低顺序的配置应捕获特定endpoint,而最高顺序的配置为默认值。在您的例子中,这意味着APIendpoint应该是@Order(1),默认值应该是@orders

此外,您没有在代码中将过滤器添加到http对象中,因此需要在它工作之前添加过滤器

在不相关的说明中,我认为您应该从封装类中删除扩展WebSecurityConfigurerAdapter@Configuration它,因为它包含spring需要在启动时获取的配置属性,但不是WebSecurityConfigurerAdapter实例,因为您的子类现在是

 类似资料:
  • 我正在尝试为自己构建一个仪表板,为我使用的一些应用程序提供基于SAML的身份验证。 从我作为测试平台构建的: 我正在使用一个登录名作为我要使用的应用程序的身份提供者。 举个例子:对于Netflix,我被重新路由到Netflix页面,我的用户ID和密码被预先填入其中,就像密码管理器的工作方式一样。(它使用OneLogin的扩展名) Netflix是否允许基于SAML的单点登录身份验证?我无法从谷歌搜

  • 我不熟悉RESTful API的概念。 我正在为一家在线商店设计一个RESTful API。 我没有正确理解SSL上的基本HTTP身份验证的概念。 这是否意味着对于每个请求,用户都必须再次输入他/她的用户名和密码? 有人能详细解释它的功能和用途吗?

  • 我卡住试图弄清楚如何通过使用此留档给出的REST api来验证用户访问JIRA的JSON数据:https://developer.atlassian.com/server/jira/platform/jira-rest-api-example-basic-authentication-6291732/ Items是一个数组,它允许我从jira获取URL提供的JSON数据中的值。 我无法接收数据,因

  • 本文向大家介绍基于javascript简单实现对身份证校验,包括了基于javascript简单实现对身份证校验的使用技巧和注意事项,需要的朋友参考一下 本文实例介绍了javascript简单实现对身份证的校验的关键性代码,分享给大家供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家实现javascript身份证校验有所帮助。

  • 我正在使用(来自命名空间)在应用程序中对Active Directory进行身份验证(我正在使用函数)。 身份验证工作正常,当我在Active Directory中重置用户密码并强制他在下一次登录时更改密码时,我无法对用户进行身份验证。 我尝试改变身份验证的方式,我使用了(命名空间),身份验证工作正常,当我重置用户密码并强制用户在下一次登录时更改密码时,我无法对该用户进行身份验证,如果我只是重置密

  • 所以我正忙着为twitter开发一个应用程序,我希望人们使用PIN进行身份验证。(https://dev.twitter.com/oauth/pin-based). 要向人们显示PIN码,我需要使用以下命令:https://dev.twitter.com/oauth/reference/get/oauth/authorize 那里的例子说:https://api.twitter.com/oauth