我们能否根据 Mediatype 加载不同的安全配置,即一种 REST 和一种用于 Web?

Posted

技术标签:

【中文标题】我们能否根据 Mediatype 加载不同的安全配置,即一种 REST 和一种用于 Web?【英文标题】:Can we load different security configuration based on Mediatype, i.e. One of REST and one for web? 【发布时间】:2020-10-29 15:32:50 【问题描述】:

我已经开发了一个常规的 spring mvc 应用程序,并且想添加一些用于开发移动应用程序的 rest 控制器。我已经编写了 rest 控制器和多 spring 安全配置。

问题是,它们是优先的,因此两者都同时加载,整个应用程序崩溃。我想根据它收到的请求类型使用一个,例如,如果我从 Postman 请求,请休息API 安全配置应该可以工作,如果我们使用 Web,Web 安全配置应该可以工作。

这是我的实现,我不知道如何实现,请提出正确的方法。由于分离了整个 Thymeleaf 和 MVC 控制器,并且在这个阶段完全与 Angular 一起移动是不可能的。

请注意,我们在 /v1/ap1/** 中定义了所有 rest api,而所有其他 mvc 部分都在 /**

任何 cmets,建议将不胜感激,因为 3 天以来它正在扼杀我的日子。提前致谢

@Configuration
@EnableWebSecurity
public class SecurityConfig 
     // ... other codes
     @Configuration
     @Order(1)
     public static class RestAPISecurity extends WebSecurityConfigurerAdapter 
       //.. other codes
       protected void configure(HttpSecurity http) throws Exception 
        http
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/signin/**").permitAll()
                .antMatchers("/api/v1/**").hasAnyAuthority("ADMIN", "USER")
                .antMatchers("/api/users/**").hasAuthority("ADMIN")
                .antMatchers("/api/v1/**").authenticated()
                .antMatchers("/login", "/logout", "/register", "/j_spring_security_check").permitAll()
                .anyRequest().authenticated()
                .and().exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).accessDeniedHandler(new CustomAccessDeniedHandler());
    
// .. other codes
    @Configuration
    @Order(2)
    public static class MVCSecurityConfiguration extends WebSecurityConfigurerAdapter 
        //.. other codes
        // form login and other MVC stuffs
    

【问题讨论】:

【参考方案1】:

您可以为第一个 spring 安全过滤器链添加请求匹配器,其他所有内容都转到第二个链

    protected void configure(HttpSecurity http) throws Exception 
        http.requestMatcher(httpServletRequest -> 
              String userAgent = httpServletRequest.getHeader("User-Agent");      
              //If you want to check based on content type
              String contentType = httpServletRequest.getContentType();

              return userAgent.contains("....")
              //check what value postman sends as user agent and use it
            )
            .sessionManagement()
            ....
    

【讨论】:

感谢@Kavithakaran,这对我有用,我能够解决我的问题,我困惑了 3 天,非常感谢。 请注意,不要使用这种机制来保证一个安全而另一个不安全。因为任何人都可以添加标题并通过。因此,请确保两种配置都需要身份验证和授权 是的,我确实已经实现了这些东西,我将发布详细的解决方案。互联网上充斥着 hello world 之类的东西。

以上是关于我们能否根据 Mediatype 加载不同的安全配置,即一种 REST 和一种用于 Web?的主要内容,如果未能解决你的问题,请参考以下文章

WebGL开发:加载图片配准

Azure Devops Server 能否预配硬件

正确使用 Apache Tika MediaType

java中的全局变量和静态变量是在编译时分配内存还是在加载时分配内存??

如何在 apache 磁贴中分配角色

重新分配新分配的内存是不是安全?