【问题标题】:Enable Spring Security authentication depending on client URL根据客户端 URL 启用 Spring Security 身份验证
【发布时间】:2021-12-18 20:29:02
【问题描述】:

我有一个使用 JWT 身份验证的 Spring 应用程序。

我想知道你是否有可能根据哪个客户端访问我的后端来释放路由,例如:

  • clientA:8080 - 允许 /health 路由而无需身份验证
  • clientB:8081 - 在没有 JWT 身份验证的情况下不允许有 /health 路由。

我曾尝试过这样的事情:

http.authorizeRequests().antMatchers("http://clientA/health").permitAll()

但是没有用。

【问题讨论】:

  • 如何在 Spring 应用中识别客户端?不同的客户端使用不同的 URL 吗?
  • 没错,这些是不同的 URL。只有 1 个客户端需要清除所有路由,其余的将全部使用身份验证。
  • 从安全的角度来看,这样做并不理想。因为如果“秘密”网址丢失,那么某人将拥有无限访问权限。
  • 你控制暴露的端点 URI 吗?客户是否可能拥有他们将使用的固定 IP?
  • 至于安全性,你可以放心,这是为了一系列的测试。是的,我可以控制客户端 IP,只有 2 个,它们是内部的。

标签: java spring spring-security


【解决方案1】:

我强烈建议不要使用这种不是强身份验证机制的身份验证。但是,您可以像对多个身份验证所做的那样实现。基本上你需要多个WebSecurityConfigurerAdapter 和一个requestMatcher

这是一个快速示例(不要这样做):

安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfigurations {


    @Configuration
    @Order(1)
    public static class NoAuth extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http.requestMatcher(r -> r.getRequestURL().toString().startsWith("http://localhost:8081"))
                    .authorizeRequests()
                    .anyRequest().permitAll();
        }
    }

    @Configuration
    @Order(2)
    public static class Auth extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            final byte[] salt = "random".getBytes(StandardCharsets.UTF_8);
            KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256);
            SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
            System.out.println(Base64.getEncoder().encodeToString(key.getEncoded()));

            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .oauth2ResourceServer()
                    .jwt()
                    .decoder(NimbusJwtDecoder.withSecretKey(key).build());
        }
    }

}

应用配置:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public ServletWebServerFactory serverContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createConnector());
        return tomcat;
    }

    private Connector createConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setPort(8081);
        connector.setScheme("http");
        connector.setSecure(false);
        return connector;
    }

}

控制器

@RestController
public class HealthApi {

    @GetMapping("/health")
    public String health() {
        return "healthy";
    }

}

你可以用 curl 测试一下:

curl -v localhost:8081/health

200 OK 健康

curl -v localhost:8080/health

401

curl -v -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.LUn3qZESwtUIbXrD3WSd3CNEOTwbKV9x2IahoLUCyAs" localhost:8080/health

200 OK 健康

【讨论】:

    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 2013-07-20
    • 2019-06-13
    • 1970-01-01
    • 2018-08-31
    • 2018-06-15
    • 2013-01-08
    • 2014-07-29
    相关资源
    最近更新 更多