Spring security - 简单的多重安全现在工作[重复]

Posted

技术标签:

【中文标题】Spring security - 简单的多重安全现在工作[重复]【英文标题】:Spring security - Simple Multi Security now working [duplicate] 【发布时间】:2021-09-15 20:02:19 【问题描述】:

我正在处理这个问题,从 7 小时前开始,我找不到解释,为简单起见,我只是将示例做得更小一些。 我需要一些具有安全访问权限 (JWT) 的 URL,以及具有表单登录的其他路径(仪表板)。

这是我的代码:

@EnableWebSecurity
public class MultiHttpSecurityConfig 

@Autowired
private UserDetailsService jwtUserDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
    auth
        .userDetailsService(jwtUserDetailsService)
        .passwordEncoder(passwordEncoder());


@Bean
public PasswordEncoder passwordEncoder() 
    return NoOpPasswordEncoder.getInstance();


@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter 

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    protected void configure(HttpSecurity http) throws Exception 

        http
            .csrf().disable()
                // Get Request and /Authenticate do not need authentication
            .authorizeRequests()
                .antMatchers("/authenticate", "/authenticate/**").permitAll()
                .antMatchers(HttpMethod.GET, "/api/**").permitAll()
                // all others do need authentication
                .anyRequest().authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    


@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http
            .authorizeRequests()
                .antMatchers("/dashboard/index.html").authenticated()
                .and()
            .formLogin();
    

这个例子很有效,JWT 机制很好用。 它唯一不起作用的是表单登录。当我点击浏览器localhost:8080/dashboard/index.html 时,文件就会出现。

这是我需要的:

/authorize --> 任何人都可以点击该 URL 来获取 JWT 令牌

/api -->获取方法不需要授权

/api --> 所有其他动词,都需要一个记号。

/dashboard/index.html -->应该会出现一个表单登录。

我知道anyRequest().authenticated(),它在第一个配置中,但如果我什至评论那行,第二个Order 将被完全忽略。

我应该添加或删除什么来实现我的想法?

【问题讨论】:

嗨!我试过了,但没有运气。即使我删除了订单,我也会得到:引起:java.lang.IllegalStateException:WebSecurityConfigurers 上的@Order 必须是唯一的。 这能回答你的问题吗? Multiple WebSecurityConfigurerAdapters: JWT authentication and form login in spring security 嗨!是的,我之前尝试过,但有 2 个问题: 1-给定/解决方案代码无法编译,我在每个 authenticated() 方法之后添加了 and() 2-进行更正后,在浏览器中当我点击 /dashboard 时,我看到一个登录,没关系。但是当我尝试使用例如 Postman 访问我的 API 并点击 localhost:8080/api/whatever 时,响应是登录页面的 html! 看,我根据您在您提到的帖子中给出的答案创建了一个要点。 gist.github.com/alexisjk/ea1fa42b043ab885ad782e9fd024010d 我可以让它工作 autenticate URL , /admin url(我看到一个表单登录),但是任何人都可以点击 /api 并且该 url 应该被验证。 你试过@Ordered(Order.HighestPrecedence + 99) 吗? 【参考方案1】:

在您的FormLoginWebSecurityConfigurerAdapter 中,antMatchers() 应在authorizeRequests() 之前调用 - 这表明此过滤器链仅将请求应用于/dashboard/index.html

http.antMatcher("/dashboard/index.html")
    .authorizeRequests()
        .anyRequest().authenticated() // since this filter chain only apply to /dashboard/index.html, don't need use antMatchers() to check again
        .and()
    .formLogin();

欲了解更多信息:https://docs.spring.io/spring-security/site/docs/current/reference/html5/#multiple-httpsecurity

第二个问题是yourFormLoginWebSecurityConfigurerAdapter的顺序必须在(小于)ApiWebSecurityConfigurationAdapter之前。 WebSecurityConfigurerAdapter 的默认@Order 为100,因此您应该在FormLoginWebSecurityConfigurerAdapter 上注释@Order(0)

【讨论】:

嗨!谢谢你的时间。我试过了,但没有运气。我不得不将 http.antMatchers 更改为 http.antMatcher ,因为它无法编译。当我点击 localhost:8080/dashboard/index.html 时,我得到: Whitelabel 错误页面 此应用程序没有 /error 的显式映射,因此您将其视为后备。 Mon Jul 05 09:43:44 ART 2021 出现意外错误(类型=禁止,状态=403)。看来,它正在再次应用另一个过滤器 (JWT)。 现在有趣的是,如果我删除 ApiWebSecurityConfigurationAdapter ,我仍然会得到与上面告诉你的相同的 Whitelabel 错误。这是一个谜题! 我必须让表单出现的唯一方法是这样做:http.authorizeRequests().antMatchers("/dashboard/index.html").authenticated().and().formLogin( );但是现在,问题是对 /api 的任何请求都会返回 403,即使 /authenticate 具有 permitAll 规则。很奇怪 @AlexisYair http.antMatcher 是正确的,Dickson 打错了。但是您还必须按照 Dickson 所写的那样更改顺序。但是,您还有另一个问题,请参阅:***.com/questions/39314176/… 是的,我错了,我已经更新了答案。但除此之外,它应该有效。您能否显示 403 响应的调试日志/异常堆栈跟踪?

以上是关于Spring security - 简单的多重安全现在工作[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Reactive-Spring-Security-5.1.3.RELEASE,多重授权

Spring Security 多重过滤器链问题

使用自己的登录表单进行太多重定向 - Spring Security

spring security - 针对不同 CURL 模式的多重身份验证

Spring Security最简单全面教程(带Demo)

Grails:Spring Security 插件对于简单的安全性来说是不是过于强大