是否有一种方法可以在类中使用局部变量(在下面的authorizedRoles中),该类具有所有角色,以为hasAnyRole值授予对端点的访问权限?例如,我想要一个在配置中定义的角色列表,并像这样在@PreAuthorize中填充hasAnyRole:
@Controller("myController")
public class MyController {
private String authorizedRoles;
@Autowired
public MyController(ObjectMapper objectMapper, @Value("#{'${security.authorized-roles}'.split(',')}") String authorizedRoles) {
this.objectMapper = objectMapper;
this.request = request;
this.authorizedRoles = authorizedRoles;
}
@RequestMapping(value = "/id", produces = { "application/json" }, consumes = { "application/json" }, method = RequestMethod.POST)
@PreAuthorize("hasAnyRole('#myController.authorizedRoles')")
public ResponseEntity<IdResponse> idPost(@RequestBody IdRequest body) {
...
}
您无法通过SpEL那样访问私有字段;您需要添加public String getAuthorizedRoles()
,当您引用authorizedRoles
属性时,SpEL会调用它。 SpEL知道JavaBean约定。
编辑
[hasAnyRole()
取String[]
。
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class So59419703Application extends GlobalAuthenticationConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(So59419703Application.class, args);
}
@Autowired
private Foo foo;
@Bean
public ApplicationRunner runner() {
return args -> {
SecurityContext ctx = SecurityContextHolder.createEmptyContext();
ctx.setAuthentication(new UsernamePasswordAuthenticationToken("foo", "bar"));
SecurityContextHolder.setContext(ctx);
System.out.println(foo.bar());
};
}
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("foo").password("bar").roles("baz");
}
public interface Foo {
String bar();
String[] getRoles();
}
@Component("foo")
public static class FooImpl implements Foo {
private final String[] roles = StringUtils.commaDelimitedListToStringArray("admin,user,baz");
@Override
@PreAuthorize("hasAnyRole(@foo.roles)")
public String bar() {
return "authOk";
}
@Override
public String[] getRoles() {
return this.roles;
}
}
}
authOk