Reputation: 2465
Is there a way to use a local variable in a class (authorizedRoles below), that is set with all the roles to grant access to an endpoint for the hasAnyRole value? For example, I want to have a list of roles, defined in a config, and populate the hasAnyRole in @PreAuthorize like so:
@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) {
...
}
Upvotes: 2
Views: 3180
Reputation: 174729
You can't access a private field that way with SpEL; you need to add public String getAuthorizedRoles()
and SpEL will call it when you refer to the authorizedRoles
property. SpEL is aware of JavaBean conventions.
EDIT
hasAnyRole()
takes a 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
Upvotes: 2