Reputation: 9
Currently I am writing my own custom @PreAuthorize annotation. My case is as follows,
KeyCloak JWT permission structure:
"authorization": {
"permissions": [
{
"scopes": [
"GET",
"DELETE",
"POST"
],
"rsid": "6ae9895f-3766-464f-82c4-44f598ec2a93",
"rsname": "record"
}
]
}
application.property:
auth:
data:
name1: record
name2: device
Property Detail Component class:
@ConfigurationProperties(prefix = "auth")
@Component
public class SecurityProperty {
private Map<String, String> data;
....
}
Controller:
@RequestMapping (method = RequestMethod.GET,value = "/api/records",
produces = {"application/json"})
@PreAuthorize ("hasAuthority (@securityProperty.getData(). get('name1') "
+ "+ ': GET')")
ResponseEntity<List<SomeDTO>> getRecords() {
...Some Logic
}
@RequestMapping(method = RequestMethod.GET,value = "/api/devices",
produces = { "application/json" })
@PreAuthorize("hasAuthority(@securityProperty.getResources().get('name2') "
+ "+ ':GET')")
ResponseEntity<List<SomeDTO>> getDevices() {
...Some Logic
}
@Retention(RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@PreAuthorize("hasAuthority(@securityProperty.getResources().get(#resource)"
+ ".concat(':GET'))")
public @interface CustomPreAuthorize {
String resource();
}
And used this in controller
@RequestMapping (method = RequestMethod.GET,value = "/api/devices",
produces = {"application/json"})
@CustomPreAuthorize (resource = "name2")
ResponseEntity<List<SomeDTO>> getDevices() {
...Some Logic
}
Issue:
Failed to evaluate expression 'hasAuthority(@securityProperty.getResources().get(#resource).concat(':GET'))"
Upvotes: 1
Views: 377
Reputation: 9
Since there is no reply yet for the required fix, for now we have fixed this by adding the Aspect for the annotation and proceed with manual authority check using the SecurityContextHolder.
@Before("@annotation(CustomPreAuthorize)")
void annotationPointcut() {
//business logic
}
We will check for the other solutions actively and post if we achieve it in more better way.
Upvotes: 0