Spring Security 笔记(3)——授权

测试用户(暂用 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 了:

加载评论