spring - 您可以在 @PreAuthorize 中使用 SpEL 引用实例属性吗?
问题描述
有没有办法在类中使用局部变量(下面的授权角色),该变量设置了所有角色以授予对 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
推荐阅读
- google-app-engine - appengine.googleapis:method() 只需要 1 个参数(给定 2 个)
- android - 如何从使用 getIntent() 接收数据的活动发送数据?
- android - 没有数据返回时如何清除我的 Firebase ListView?
- r - 我的第一个 R Shiny,我如何将 selectinput 与 renderplot(ggplot) 结合起来?
- reactjs - 每次我在我的应用程序中更改页面时,Redux Store 的大小都会增长吗?
- javascript - TypeError: undefined is not an object (评估 '$next[0].offsetWidth')
- c - C 编程错误:结构的未定义符号(Keil 错误 L6218E)
- node.js - 设置音频。当前时间;带有从快递服务器发送的歌曲缓冲区
- pandas - 熊猫中特定列值的日期之间的累积差异
- kotlin - 是插入或更新使用 Comparator 的 kotlin 可变列表的 std 扩展吗?