问题
I am using the latest Spring Boot + Spring Boot Starter Security for a simple proxy application. The goal is to launch the application with a single route/method:
@RequestMapping(value = "/api/register",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<?> register(Registration registration) {
With a security configuration of:
@Override
protected void configure(HttpSecurity http) throws Exception {
this.http = http
.authorizeRequests()
.antMatchers("/api/register").hasAuthority(AuthorityConstants.ADMIN)
.and();
}
public HttpSecurity getHttpSecurity() {
return http;
}
The goal of the application would be to accept registration requests of the form:
{
"route":"/api/foo/bar",
"proxy_location": "http://back-end-server/path/to/resource",
"role": "some-authority"
}
And then the application would add an /api/foo/bar
route with a pre-defined method that will proxy (forward) future requests to the backend service.
I know this is a little goofy, the real use-case involves websockets and dynamic creation of topics.
The issue I'm facing is that I cannot seem to update the security configuration after the SecurityConfigurer has completed.
In the code sample above I am caching the HttpSecurity
object given to my SecurityConfigurer
and then trying to use that object again to configure a new route:
@Inject
private SecurityConfigurer security;
@RequestMapping(value = "/api/register",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<?> allowGetAccounts(Registration registration) {
try {
security.getHttpSecurity()
.authorizeRequests()
.antMatchers(registration.getRoute()).hasAuthority(registration.getRole());
...
} catch (Exception e) {
log.error("Updating security failed!", e);
}
return new ResponseEntity<>(null, HttpStatus.OK);
}
Is there any way to update the security configuration dynamically during runtime?
Also, if anyone has any notes on creating websocket topics dynamically that would be appreciated too!
回答1:
You have several options:
use
antchMatcher("/some/path").access("@someBean.hasAccess(authentication)")
. This allows you basically use any bean in your application context to apply the validation you need.Use
@PreAuthorize("@someBean.hasAccess(authentication)")
on youRequestMapping
annotated method. Same idea as before but as an interceptor on the endpoint itself.Implement your own
SecurityExpressionHandler
and plug it intohttp.authorizeRequests().expressionHandler(...)
.Implement your own Security filter that handles whatever you need.
来源:https://stackoverflow.com/questions/39089494/modify-spring-security-config-at-runtime