【问题标题】:Spring Security permitAll not allowing anonymous accessSpring Security permitAll 不允许匿名访问
【发布时间】:2014-09-02 00:27:45
【问题描述】:

我有一个方法,我想同时允许匿名和经过身份验证的访问。

我正在使用 Spring Security 3.2.4 和基于 Java 的配置。

覆盖的配置方法(在我扩展WebSecurityConfigurerAdapter 的自定义配置类中)具有以下http 块:

    http
        .addFilterBefore(muiltpartFilter, ChannelProcessingFilter.class)
        .addFilterBefore(cf, ChannelProcessingFilter.class)
        .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
        .authorizeRequests()
            .antMatchers("/ping**")
            .permitAll()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
        .logoutSuccessUrl("/login");

ping 请求处理程序和方法位于还包含登录处理程序的控制器中,并且它没有单独的 @PreAuthorize 或其他可能导致问题的注释。

问题是匿名访问被拒绝,用户被重定向到登录页面。

在调试级别登录,我看到来自 Spring Security 的以下反馈:

[2014-07-11 13:18:04,483] [DEBUG] [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /ping; Attributes: [authenticated]
[2014-07-11 13:18:04,483] [DEBUG] [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6faad796: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffffa64e: RemoteIpAddress: 192.168.2.128; SessionId: 0EF6B13BBA5F00C020FF9C35A6E3FBA9; Granted Authorities: ROLE_ANONYMOUS
[2014-07-11 13:18:04,483] [DEBUG] [org.springframework.security.access.vote.AffirmativeBased] Voter: org.springframework.security.web.access.expression.WebExpressionVoter@123f2882, returned: -1
[2014-07-11 13:18:04,483] [DEBUG] [org.springframework.security.web.access.ExceptionTranslationFilter] Access is denied (user is anonymous); redirecting to authentication entry point

我想要完成的是有一个可以在任何时候调用的方法,它会发送一个回复,指示请求是否在登录的会话中。

【问题讨论】:

  • 如果使用“/ping”或“/ping*”作为模式会发生什么?
  • 你是 Luke Taylor,我在 Spring Security Javadoc cmets 中多次看到他的名字吗?如果是这样,那就太荣幸了!不幸的是,使用 /ping 和使用 /ping* 的行为是相同的。
  • 你的authorizeRequests().anyRequest().authenticated()不应该是最后一个吗?在 XML 中,元素的顺序很重要,所以我可以想象这同样适用于 java config。
  • @M.Deinum,我通过将 .authorizeRequests().antMatchers("/ping**").permitAll() 放在之前尝试了您的建议,现在它可以工作了。谢谢!

标签: java spring spring-mvc spring-security


【解决方案1】:

我为这个问题苦苦挣扎了一天。我最终要做的是从我的过滤器中删除@Component 注释,并手动实例化它,如this 回答中所述。

所以对于原始问题,这看起来像:

http
    .addFilterBefore(new MultiPartFilter(), ChannelProcessingFilter.class)
    .addFilterBefore(new OtherFilter(), ChannelProcessingFilter.class)
    .authorizeRequests() // ... rest omitted for brevity

我还必须通过覆盖 configure(WebSecurity web) 来完全从 Spring Security 中删除这些端点,如 J. Perez 的回答中所述:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/ping**");
}

【讨论】:

    【解决方案2】:
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.anonymous().and()...;
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/ping**");
    }
    

    【讨论】:

      【解决方案3】:

      需要添加.annonymous()

      http
          .addFilterBefore(muiltpartFilter, ChannelProcessingFilter.class)
          .addFilterBefore(cf, ChannelProcessingFilter.class)
          .anonymous().and()
          .authorizeRequests().anyRequest().authenticated().and()
              .authorizeRequests()
                  .antMatchers("/ping**")
                  .permitAll()
                  .and()
              .formLogin()
                  .loginPage("/login")
                  .permitAll()
                  .and()
              .logout()
                  .logoutUrl("/logout")
              .logoutSuccessUrl("/login");
      

      引用自:https://stackoverflow.com/a/25280897/256245

      【讨论】:

      • 您先生救了我的命!谢谢。 ... 'anonymous()' 有效!
      • 哦,我多么希望它能够工作。我得到:嵌套异常是 java.lang.IllegalStateException: Can't configure antMatchers after anyRequest。 springBootVersion = '2.3.3.RELEASE'
      • FWIW,我必须将 .anonymous() 放在过滤器链的末尾才能让事情正常工作。 .anonymous 的行为似乎是添加一个“匿名”用户,所以如果你把它放在过滤器链的前面,它会将它添加为用户并称之为好。
      【解决方案4】:

      我看到了同样的问题。确保您没有致电
      super.configure(http);
      anyRequest().authenticated();
      默认调用。

      【讨论】:

      • 我对此赞不绝口。我已经尝试并放弃了 Spring 很多次,因为我永远无法让 Spring Security 工作;一直以来,这就是原因。非常感谢!
      • @W.K.S 我为你的这个好答案添加了一个赞成票:D
      • 可悲的是,这是复制和粘贴的最大罪过。
      【解决方案5】:

      权限顺序很重要,当我这样配置时它起作用:

      .authorizeRequests()
              .antMatchers("/ping**")
              .permitAll()
              .and()
      .authorizeRequests()
              .anyRequest()
              .authenticated()
              .and()
      

      【讨论】:

        猜你喜欢
        • 2015-10-09
        • 2019-08-19
        • 2020-05-10
        • 1970-01-01
        • 2019-07-21
        • 2018-12-10
        • 2021-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多