From c0886728d981078980305a5c828f8b541e040bf2 Mon Sep 17 00:00:00 2001 From: doggerz Date: Fri, 11 Oct 2024 11:15:06 +0300 Subject: [PATCH] update authorization interceptor to be compatible with new security api model --- .../security/AuthorizationInterceptor.java | 12 +++- .../security/cache/TokenCacheService.java | 43 ++++-------- .../config/SecurityConfiguration.java | 8 ++- .../security/dto/RoleAttachmentsDTO.java | 33 ---------- .../earth/angelson/security/dto/RoleDTO.java | 7 ++ .../security/dto/RoleWithRuleDTO.java | 43 ------------ .../earth/angelson/security/dto/RuleDTO.java | 66 ------------------- .../earth/angelson/security/dto/UserDTO.java | 8 +++ .../security/dto/UserRoleAttachmentsDTO.java | 7 ++ src/main/resources/application.yaml | 6 +- 10 files changed, 53 insertions(+), 180 deletions(-) delete mode 100644 src/main/java/earth/angelson/security/dto/RoleAttachmentsDTO.java create mode 100644 src/main/java/earth/angelson/security/dto/RoleDTO.java delete mode 100644 src/main/java/earth/angelson/security/dto/RoleWithRuleDTO.java delete mode 100644 src/main/java/earth/angelson/security/dto/RuleDTO.java create mode 100644 src/main/java/earth/angelson/security/dto/UserDTO.java create mode 100644 src/main/java/earth/angelson/security/dto/UserRoleAttachmentsDTO.java diff --git a/src/main/java/earth/angelson/security/AuthorizationInterceptor.java b/src/main/java/earth/angelson/security/AuthorizationInterceptor.java index 179a903bb13..edbde3606fa 100644 --- a/src/main/java/earth/angelson/security/AuthorizationInterceptor.java +++ b/src/main/java/earth/angelson/security/AuthorizationInterceptor.java @@ -1,5 +1,6 @@ package earth.angelson.security; +import ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder; import earth.angelson.security.cache.TokenCacheService; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule; @@ -10,16 +11,23 @@ public class AuthorizationInterceptor extends ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor { private final TokenCacheService tokenCacheService; + private final List allowedUrls; - public AuthorizationInterceptor(TokenCacheService tokenCacheService) { + public AuthorizationInterceptor(TokenCacheService tokenCacheService, List allowedUrls) { this.tokenCacheService = tokenCacheService; + this.allowedUrls = allowedUrls; } @Override public List buildRuleList(RequestDetails theRequestDetails) { String authHeader = theRequestDetails.getHeader("Authorization"); - //todo if service return empty unauthorized request 403 + for (String url : allowedUrls) { + if (theRequestDetails.getCompleteUrl().contains(url)) { + return new RuleBuilder().allowAll().build(); + } + } + return tokenCacheService.getData(authHeader); } } diff --git a/src/main/java/earth/angelson/security/cache/TokenCacheService.java b/src/main/java/earth/angelson/security/cache/TokenCacheService.java index f8d15c51fda..7a6f2382388 100644 --- a/src/main/java/earth/angelson/security/cache/TokenCacheService.java +++ b/src/main/java/earth/angelson/security/cache/TokenCacheService.java @@ -1,9 +1,9 @@ package earth.angelson.security.cache; -import earth.angelson.security.dto.RoleAttachmentsDTO; import ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule; import ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder; +import earth.angelson.security.dto.UserRoleAttachmentsDTO; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -29,43 +29,24 @@ public List getData(String token) { headers.set("Authorization", token); // Create HttpEntity with headers - HttpEntity entity = new HttpEntity<>(headers); + HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = - restTemplate.exchange(url, HttpMethod.GET, entity, RoleAttachmentsDTO.class); + ResponseEntity response = + restTemplate.exchange(url, HttpMethod.GET, entity, UserRoleAttachmentsDTO.class); if (response.getBody() != null) { var builder = new RuleBuilder().build(); - var role = response.getBody(); - role.getRoles().stream().forEach(roleWithRuleDTO -> { - roleWithRuleDTO.getRules().forEach(rule -> { - switch (rule.getOperation()) { - case "READ": { - builder.addAll(new RuleBuilder() - .allow() - .read() - .allResources() - .withAnyId() - .build()); - break; - } - case "WRITE": { - builder.addAll(new RuleBuilder() - .allow() - .write() - .allResources() - .withAnyId() - .build()); - break; - } - case "ALL": { - builder.addAll(new RuleBuilder().allowAll().build()); - break; - } + var userInfo = response.getBody(); + + userInfo.user().roles().forEach(role -> { + switch (role.name().toUpperCase()) { + case "ADMIN", "PRACTITIONER", "OPERATOR": { + builder.addAll(new RuleBuilder().allowAll().build()); + break; } + } - }); }); return builder; } diff --git a/src/main/java/earth/angelson/security/config/SecurityConfiguration.java b/src/main/java/earth/angelson/security/config/SecurityConfiguration.java index c4f63dc7799..8e89b4f8c51 100644 --- a/src/main/java/earth/angelson/security/config/SecurityConfiguration.java +++ b/src/main/java/earth/angelson/security/config/SecurityConfiguration.java @@ -10,6 +10,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.List; import java.util.concurrent.TimeUnit; @EnableCaching @@ -17,9 +18,12 @@ public class SecurityConfiguration { - @Value("${security.service.url:http://localhost:8081/account/info}") + @Value("${security.service.url:http://localhost:8090/account/info}") private String securityServiceUrl; + @Value("#{'${security.service.allowed-urls:swagger-ui,api-docs}'.split(',')}") + private List allowedUrls; + @Bean public TokenCacheService tokenCacheService() { return new TokenCacheService(securityServiceUrl); @@ -27,7 +31,7 @@ public TokenCacheService tokenCacheService() { @Bean public AuthorizationInterceptor authorizationInterceptor(TokenCacheService tokenCacheService) { - return new AuthorizationInterceptor(tokenCacheService); + return new AuthorizationInterceptor(tokenCacheService, allowedUrls); } @Bean diff --git a/src/main/java/earth/angelson/security/dto/RoleAttachmentsDTO.java b/src/main/java/earth/angelson/security/dto/RoleAttachmentsDTO.java deleted file mode 100644 index 206472930cb..00000000000 --- a/src/main/java/earth/angelson/security/dto/RoleAttachmentsDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package earth.angelson.security.dto; - -import java.util.Map; -import java.util.Set; - -public class RoleAttachmentsDTO { - private Set roles; - private Set> attachments; - - public RoleAttachmentsDTO() { - } - - public RoleAttachmentsDTO(Set roles, Set> attachments) { - this.roles = roles; - this.attachments = attachments; - } - - public Set getRoles() { - return roles; - } - - public void setRoles(Set roles) { - this.roles = roles; - } - - public Set> getAttachments() { - return attachments; - } - - public void setAttachments(Set> attachments) { - this.attachments = attachments; - } -} diff --git a/src/main/java/earth/angelson/security/dto/RoleDTO.java b/src/main/java/earth/angelson/security/dto/RoleDTO.java new file mode 100644 index 00000000000..cbb7edf41e9 --- /dev/null +++ b/src/main/java/earth/angelson/security/dto/RoleDTO.java @@ -0,0 +1,7 @@ +package earth.angelson.security.dto; + +import java.util.UUID; + +public record RoleDTO(UUID id, String name) { +} + diff --git a/src/main/java/earth/angelson/security/dto/RoleWithRuleDTO.java b/src/main/java/earth/angelson/security/dto/RoleWithRuleDTO.java deleted file mode 100644 index bbc7a0f99b2..00000000000 --- a/src/main/java/earth/angelson/security/dto/RoleWithRuleDTO.java +++ /dev/null @@ -1,43 +0,0 @@ -package earth.angelson.security.dto; - -import java.util.Set; -import java.util.UUID; - -public class RoleWithRuleDTO { - private UUID id; - private String roleName; - private Set rules; - - public RoleWithRuleDTO() { - } - - public RoleWithRuleDTO(UUID id, String roleName, Set rules) { - this.id = id; - this.roleName = roleName; - this.rules = rules; - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getRoleName() { - return roleName; - } - - public void setRoleName(String roleName) { - this.roleName = roleName; - } - - public Set getRules() { - return rules; - } - - public void setRules(Set rules) { - this.rules = rules; - } -} diff --git a/src/main/java/earth/angelson/security/dto/RuleDTO.java b/src/main/java/earth/angelson/security/dto/RuleDTO.java deleted file mode 100644 index 5fb981c06d4..00000000000 --- a/src/main/java/earth/angelson/security/dto/RuleDTO.java +++ /dev/null @@ -1,66 +0,0 @@ -package earth.angelson.security.dto; - - -import java.util.List; -import java.util.UUID; - - -public class RuleDTO { - - private UUID id; - private String name; - private String operation; - private List resource; - private String filter; - - public RuleDTO() { - } - - public RuleDTO(UUID id, String name, String operation, List resource, String filter) { - this.id = id; - this.name = name; - this.operation = operation; - this.resource = resource; - this.filter = filter; - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getOperation() { - return operation; - } - - public void setOperation(String operation) { - this.operation = operation; - } - - public List getResource() { - return resource; - } - - public void setResource(List resource) { - this.resource = resource; - } - - public String getFilter() { - return filter; - } - - public void setFilter(String filter) { - this.filter = filter; - } -} diff --git a/src/main/java/earth/angelson/security/dto/UserDTO.java b/src/main/java/earth/angelson/security/dto/UserDTO.java new file mode 100644 index 00000000000..49697cdee8b --- /dev/null +++ b/src/main/java/earth/angelson/security/dto/UserDTO.java @@ -0,0 +1,8 @@ +package earth.angelson.security.dto; + +import java.util.Set; +import java.util.UUID; + +public record UserDTO(UUID id, String practitionerId, String organizationId, String firstName, String lastName, String username, + String password, boolean enabled, Set roles) { +} diff --git a/src/main/java/earth/angelson/security/dto/UserRoleAttachmentsDTO.java b/src/main/java/earth/angelson/security/dto/UserRoleAttachmentsDTO.java new file mode 100644 index 00000000000..6ab9dd4e6b6 --- /dev/null +++ b/src/main/java/earth/angelson/security/dto/UserRoleAttachmentsDTO.java @@ -0,0 +1,7 @@ +package earth.angelson.security.dto; + +import java.util.Set; + +public record UserRoleAttachmentsDTO(UserDTO user, Set attachments) { +} + diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 8c8e18d7315..36f6627bc40 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -168,7 +168,7 @@ hapi: # allowed_bundle_types: COLLECTION,DOCUMENT,MESSAGE,TRANSACTION,TRANSACTIONRESPONSE,BATCH,BATCHRESPONSE,HISTORY,SEARCHSET # allow_cascading_deletes: true # allow_contains_searches: true - # allow_external_references: true + allow_external_references: true # allow_multiple_delete: true # allow_override_default_search_params: true # auto_create_placeholder_reference_targets: false @@ -236,8 +236,8 @@ hapi: # comma-separated list of fully qualified interceptor classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', # or will be instantiated via reflection using an no-arg contructor; then registered with the server - #custom-interceptor-classes: - + custom-interceptor-classes: + - earth.angelson.security.AuthorizationInterceptor # comma-separated list of fully qualified provider classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', # or will be instantiated via reflection using an no-arg contructor; then registered with the server