【问题标题】:Spring Security: Not able to configure method security with java configSpring Security:无法使用 java config 配置方法安全性
【发布时间】:2014-02-01 03:36:54
【问题描述】:

我正在努力使用 java 配置的 spring 安全性来配置方法安全性。我的配置工作没有任何问题,直到我在任何控制器中使用 @Secured 注释。

Spring 安全配置:(java 配置)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
                .antMatchers("/webjars/**","/css/**", "/less/**","/img/**","/js/**");
    }

    @Autowired
    public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
        ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
        auth
          .jdbcAuthentication()
              .dataSource(dataSource)
              .usersByUsernameQuery(getUserQuery())
              .authoritiesByUsernameQuery(getAuthoritiesQuery())
              .passwordEncoder(shaPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .anyRequest().hasAuthority("BASIC_PERMISSION")
            .and()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/success-login", true)
            .failureUrl("/error-login")
            .loginProcessingUrl("/process-login")
            .usernameParameter("security_username")
            .passwordParameter("security_password")
            .permitAll() 
            .and()
        .logout()
            .logoutSuccessUrl("/login")
            .logoutUrl("/logout")
            .permitAll()
            .and()
        .rememberMe()
            .key("04E87501B3F04DB297ADB74FA8BD48CA")
            .and()
        .csrf()
            .disable();
    }

    private String getUserQuery() {
        return "SELECT username as username, password as password, active as enabled "
                + "FROM employee "
                + "WHERE username = ?";
    }

    private String getAuthoritiesQuery() {
        return "SELECT DISTINCT employee.username as username, permission.name as authority "
                + "FROM employee, employee_role, role, role_permission, permission "
                + "WHERE employee.id = employee_role.employee_id "
                + "AND role.id = employee_role.role_id "
                + "AND role.id = role_permission.role_id "
                + "AND permission.id = role_permission.permission_id "
                + "AND employee.username = ? "
                + "AND employee.active = 1";
    }

}

只要我将@Secured("EMPLOYEE_DELETE") 注释添加到任何控制器方法,我就会收到以下异常。

java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []

所以我添加了一个AuthenticationManager bean:

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

但是这会导致另一个错误:

java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer@34e81675 to already built object

看来我必须与配置的jdbcAuthentication 共享authenticationManagerBean,但我无法做到这一点。提前感谢您的帮助!

【问题讨论】:

  • 我不认为你可以提供一个完整的例子来重现这个问题?我在单独的测试中无法重现它。如果可以,请更新此内容或在 JIRA jira.springsource.org/browse/SEC-2477 上提供完整示例 另一件有帮助的事情是提供“IllegalArgumentException:期望只找到一个 bean ..”的完整堆栈跟踪,并告诉我您是否试图在任何地方自动装配 AuthenticationManager。谢谢!
  • 没关系...我终于能够始终如一地重现这一点。当然,它发生在我在这里发布之后。谢谢!

标签: java spring spring-mvc spring-security spring-java-config


【解决方案1】:

听起来您遇到了SEC-2477 中所述的订购问题。

作为一种解决方法,您应该能够将 configure 方法与 authenticationManagerBean 方法一起使用。不要使用@Autowired AuthenticationManagerBuilder 方法。

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
    auth
      .jdbcAuthentication()
          .dataSource(dataSource)
          .usersByUsernameQuery(getUserQuery())
          .authoritiesByUsernameQuery(getAuthoritiesQuery())
          .passwordEncoder(shaPasswordEncoder);
}

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

【讨论】:

  • 我一直在通过 Google 寻找如何连接 Spring MVC 以与 Spring Security 一起工作。与您在此处的评论相反,我发现唯一可行的配置是您的以下拉取请求中的配置:github.com/jhipster/jhipster-sample-app/pull/2。你能解释一下什么时候应该使用一种方法而不是另一种方法吗?
猜你喜欢
  • 2015-09-20
  • 2015-01-23
  • 2013-10-21
  • 1970-01-01
  • 2015-07-05
  • 2011-10-04
  • 1970-01-01
  • 2015-02-15
  • 2017-05-15
相关资源
最近更新 更多