3

Java で構成されたスプリング セキュリティを使用してメソッド セキュリティを構成するのに苦労しています。コントローラー内で @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 
@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

authenticationManagerBeanを構成済みと共有する必要があるようjdbcAuthenticationですが、これを行うことはできません。事前にご協力いただきありがとうございます。

4

1 に答える 1

7

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();
}
于 2014-01-31T19:36:54.377 に答える