Open
Description
Expected behaviour
Enable clients to choose path based on incoming HTTP request.
Actual behaviour
Currently opaPath
can only be set by constructor. This means that the same opaPath
will be used for all HTTP
requests. However, to better structure the policies, it would be beneficial to be able to set the opaPath
based on
the incoming HTTP request attributes (Authentication
or RequestAuthorizationContext
objects).
How to improve
- Defining
OPAPathSelector
interface in the library:
@FunctionalInterface
public interface OPAPathSelector {
String selectPath(Authentication authentication, RequestAuthorizationContext requestAuthorizationContext);
}
- This bean can be passed to the
OPAAuthorizationManager
constructor(s) and be called in the opaRequest method:
public class OPAAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
...
private OPAPathSelector opaPathSelector;
public OPAAuthorizationManager(OPAClient opaClient, OPAPathSelector opaPathSelector, ContextDataProvider newProvider, String reasonKey) {
this.opa = opaClient;
this.opaPathSelector = opaPathSelector;
this.ctxProvider = newProvider;
this.reasonKey = reasonKey;
}
...
public OPAResponse opaRequest(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
String path = opaPathSelector != null ? opaPathSelector.selectPath(authentication.get(), object) : opaPath;
if (path != null) {
logger.trace("OPA path is {}", path);
resp = opa.evaluate(
path,
iMap,
new TypeReference<OPAResponse>() {}
);
...
}
- Default implementation can be provided in
OPAAutoConfiguration
and defaultOPAAuthorizationManager
bean will be updated (depends on Add OPAAutoConfiguration to define common beans #22):
public class OpaAutoConfiguration {
...
@Bean
@ConditionalOnMissingBean
public OPAPathSelector opaPathSelector(OPAProperties opaProperties) {
return (authentication, requestAuthorizationContext) -> opaProperties.opaPath;
}
@Bean
@ConditionalOnMissingBean(OPAAuthorizationManager.class)
public OPAAuthorizationManager opaAuthorizationManager(OpaProperties opaProperties) {
return new OPAAuthorizationManager(opaClient(opaProperties), opaPathSelector(opaProperties), null, opaProperties.getReasonKey());
}
}
- Clients can then create a bean for customized
OPAPathSelector
:
@Configuration
public class OPAConfig {
@Bean
public OPAPathSelector opaPathSelector() {
return (authentication, requestAuthorizationContext) -> {
String httpRequestPath = requestAuthorizationContext.getRequest().getServletPath();
if (httpRequestPath.startsWith("/customers")) {
return "customer";
} else if (httpRequestPath.startsWith("/tickets")) {
return "ticket";
} else {
return "default";
}
};
}
}
Metadata
Assignees
Labels
No labels
Activity