antMatchers允许ADMIN所有路由,而其他角色受到限制



特定用户组应该可以访问不同的 API 路由。例如,鉴于以下HttpSecurity我们允许CUSTOMER访问GET /invoices/*。另外,我想允许ADMIN访问任何路由/**

@Override
protected void configure(HttpSecurity http) throws Exception {
http = http
.cors().and()
.csrf().disable(); // REST only
// ### Authentication
// ...
// ### Authorization
// anonymous (and all other roles)
e = e
.antMatchers(HttpMethod.POST,
"/user/account/create",
"/user/account/confirm/*",
"/feedback")
.permitAll()
.antMatchers(HttpMethod.GET,
"/" + StorageController.STORAGE_RELATIVE_PATH, // public files
"/translations/*")
.permitAll();
// role CUSTOMER
e = e
.antMatchers(HttpMethod.GET,
"/invoices",
"/invoices/*")
.hasRole(Role.CUSTOMER.toString())
.antMatchers(HttpMethod.PUT,
"/profile",
"/contracts/billingAddress")
.hasRole(Role.CUSTOMER.toString())
.antMatchers(HttpMethod.POST,
"/contracts",
"/profile/logo")
.hasRole(Role.CUSTOMER.toString());
// only ADMIN
e = e.antMatchers("/**").hasRole(Role.ADMIN.toString());
}

虽然允许ADMIN使用所有未提及的/admin/.../路由,但该角色403,例如,/invoices/*- 为什么?据我了解,指定的配置取决于顺序,因此需要/invoices/*具有CUSTOMER角色,因此ADMIN是不够的 - 对吗?

如果我添加以下内容(第CUSTOMER or ADMIN节(,它可以工作,但总是列出ADMIN角色非常麻烦。我只是希望ADMIN能够访问所有内容。

@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
// role CUSTOMER
e = e
// ... as above ...

// CUSTOMER or ADMIN
e = e
.antMatchers(HttpMethod.GET,
"/invoices/*") // AGAIN
.hasAnyRole(Role.CUSTOMER.toString(),
Role.ADMIN.toString());
// only ADMIN
e = e.antMatchers("/**").hasRole(Role.ADMIN.toString());
}

此外,我不能将ADMIN规则置于其他规则之上,因为它会排除其他角色访问任何内容。有没有办法以更优雅/更简单的方式指定我想做什么?

正如您在问题中指出的,发生此行为是因为每个匹配器都按照声明的顺序进行考虑。

/invoices的请求将首先到达以下匹配器,由于它是匹配项,因此它将应用关联的规则。

.antMatchers("/invoices").hasRole("CUSTOMER")

如果发出请求的用户只有角色"ADMIN"则他们将被拒绝访问,因为"ADMIN"不是"CUSTOMER"

选项 1

若要获取所需的行为,可以显式列出有权访问终结点的角色。

正如您提到的,这很冗长,但是,优点是它清楚地指示了一个地方允许的角色。

.antMatchers("/invoices").hasAnyRole("CUSTOMER", "ADMIN")

选项 2

如果"ADMIN"应该能够执行"CUSTOMER"可以执行的任何操作,则可以声明一个RoleHierarchy,声明任何"ADMIN"也是"CUSTOMER"

@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_CUSTOMER");
return hierarchy;
}

>符号可以被认为是"包括"的意思。

然后,任何受.hasRole("CUSTOMER")保护的端点也可以由具有角色"ADMIN"的用户访问,因为具有角色"ADMIN"意味着它们也具有角色"CUSTOMER"

最新更新