0

認証されたユーザーにのみアクセスを許可するために、ロールを使用して Spring Security の Java 構成を使用しようとしています。ログイン プロセスは機能していますが、アクセスを制限する必要があるロールを使用してログインすると、保護する必要があるルートに到達できます。http 構成の WebSecurityConfigurerAdapter クラスは次のとおりです。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
DataConfig dataConfig;

private final String QUERY_USERS = "select email, password, enabled from Account where email=?";
private final String QUERY_AUTHORITIES = "select a.email, au.authority from Account a, Authority au where a.email = au.email and a.email =?  ";

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
    .authorizeUrls()
    .antMatchers("/public/login.jsp").permitAll()
    .antMatchers("/public/home.jsp").permitAll()
    .antMatchers("/public/**").permitAll()

    .antMatchers("/secured/**").fullyAuthenticated()
    .antMatchers("/resources/clients/**").fullyAuthenticated()
    .antMatchers("/secured/user/**").hasRole("USER")
    .antMatchers("/secured/admin/**").hasRole("ADMIN")

    .and()
     .formLogin()
        .loginPage("/login")
        .loginProcessingUrl("/j_spring_security_check")
        .failureUrl("/loginfailed")
        .usernameParameter("j_username")
        .passwordParameter("j_password")

     .and()
     .logout()
        .logoutUrl("/j_spring_security_logout")     // The URL that triggers logout to occur on HTTP POST
        .logoutSuccessUrl("/logout")    // The URL to redirect to after logout has occurred
        .invalidateHttpSession(true);   // Clear the session
}

@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {

    // Use the database
    auth
    .jdbcAuthentication()
        .passwordEncoder(new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder()) 
        .dataSource(dataConfig.dataSource())

        .withDefaultSchema()
        .usersByUsernameQuery(QUERY_USERS)
        .authoritiesByUsernameQuery(QUERY_AUTHORITIES);    
    }
}

これが、セキュリティ フィルター チェーンを登録する WebApplicationInitializer クラスです。

public class DatabaseWebApplicationInitializer implements WebApplicationInitializer {

private static final Class<?>[] configurationClasses = new Class<?>[] { 
                AppConfig.class, DbConfig.class, SecurityConfig.class};

private static final String DISPATCHER_SERVLET_NAME = "dispatcher";

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    registerListener(servletContext);           
    registerDispatcherServlet(servletContext);

    registerSpringSecurityFilterChain(servletContext);
}

private void registerDispatcherServlet(ServletContext servletContext) {

    // creates an application context for direct registration of 
    // @Configuration and other @Component-annotated classes
    AnnotationConfigWebApplicationContext dispatcherContext = createContext(AppConfig.class);

    ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME,
            new DispatcherServlet(dispatcherContext));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
}

private void registerListener(ServletContext servletContext) {
    AnnotationConfigWebApplicationContext rootContext = createContext(configurationClasses);
    servletContext.addListener(new ContextLoaderListener(rootContext));
    servletContext.addListener(new RequestContextListener());
}


private void registerSpringSecurityFilterChain(ServletContext servletContext) {
    FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter(
            BeanIds.SPRING_SECURITY_FILTER_CHAIN, new DelegatingFilterProxy());
    springSecurityFilterChain.addMappingForUrlPatterns(null, false, "/*");
}

private AnnotationConfigWebApplicationContext createContext(final Class<?>... annotatedClasses) {
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

    // set the active profile
    context.getEnvironment().setActiveProfiles("dev");

    context.register(annotatedClasses);
    return context;
}

}

(ADMIN ではなく) USER の役割のみを持つ資格情報を使用してログインした場合でも、/secured/admin/**のルートにアクセスできますが、ADMIN の役割を持つユーザーのみに制限する必要があると思います。何か提案があれば教えてください。または、これの良い例を教えてください。

4

1 に答える 1

3

私はそれがあなたの.antMatchers()声明の順序に関係しているとかなり確信しています。

現在、.antMatchers("/secured/**").fullyAuthenticated()前に.antMatchers("/secured/admin/**").hasRole("ADMIN"). Spring Security はおそらくこの最初のマッチャーと照合してfullyAuthenticated()チェックを適用します。これは、 role しか持っていない場合に承認が与えられることを意味しますUSER

.antMatchers()あなたのステートメントが次のようになるように、物事を並べ替えることをお勧めします。

.antMatchers("/public/login.jsp").permitAll()
.antMatchers("/public/home.jsp").permitAll()
.antMatchers("/public/**").permitAll()
.antMatchers("/resources/clients/**").fullyAuthenticated()
.antMatchers("/secured/user/**").hasRole("USER")
.antMatchers("/secured/admin/**").hasRole("ADMIN")
.antMatchers("/secured/**").fullyAuthenticated()

このシナリオでは、Spring はステートメントにフォールバックする前に、/secured/admin/**およびリソースへの特定のアクセスについて以前のルールに一致します。/secured/user/**/secured/**

于 2013-11-04T16:52:54.597 に答える