您可以在引用实例 属性 的 @PreAuthorize 中使用 SpEL 吗?
Can you use SpEL in @PreAuthorize referencing a instance property?
有没有办法在 class(下面的 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()
,SpEL 会在您引用 authorizedRoles
属性 时调用它。 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
有没有办法在 class(下面的 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()
,SpEL 会在您引用 authorizedRoles
属性 时调用它。 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