测试用户(暂用 inMemoryAuthentication):
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("bolitao")
            .password("bolitao")
            .roles("ADMIN")
            .and()
            .withUser("test1")
            .password("test")
            .roles("USER");
}
或者:
@Override
@Bean
protected UserDetailsService userDetailsService() {
    InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
    inMemoryUserDetailsManager
            .createUser(User.withUsername("bolitao").password("bolitao").roles("ADMIN").build());
    inMemoryUserDetailsManager
            .createUser(User.withUsername("test1").password("test").roles("USER").build());
    return inMemoryUserDetailsManager;
}
URL 角色拦截
http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .antMatchers("/user/**").hasRole("USER")
        .anyRequest().authenticated()
    	// ...
注意:anyRequest 只能放在最后配,具体见源码
AbstractRequestMatcherRegistry:无参构造函数会进行
anyRequestConfigured赋值:public C anyRequest() { Assert.state(!this.anyRequestConfigured, "Can't configure anyRequest after itself"); C configurer = requestMatchers(ANY_REQUEST); this.anyRequestConfigured = true; return configurer; }设置 anyMatchers 时会调用
Assert.state()判断anyRequestConfigured的值,在 anyRequest 被配置后,任何anyMatchers都无法被配置:public C antMatchers(HttpMethod method, String... antPatterns) { Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest"); return chainRequestMatchers(RequestMatchers.antMatchers(method, antPatterns)); }
配置完毕后进行测试:
使用 test1(身份为 USER)登录后访问 /user/test 返回 user test,能够正常访问;访问 admin/test 则返回 403 Forbidden:
{
    "timestamp": "2020-11-21T03:42:38.104+00:00",
    "status": 403,
    "error": "Forbidden",
    "message": "",
    "path": "/admin/test"
}
类似的,使用 bolitao(身份为 ADMIN)登陆后访问 user/test 提示 403;而 admin/test 能够正常访问。
ROLE 继承
按常理,ADMIN 应该能够访问角色权限为 USER 的 URL,因此需要角色继承,实现如下:
@Bean
RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
    return roleHierarchy;
}
当指定 ROLE_ADMIN > ROLE_USER 后,就可以使用 ADMIN 角色访问权限是 USER 的 URL 了:
