Skip to content

Commit 2dc8d18

Browse files
Merge pull request #167 from NHSDigital/dev/NPA-4599/Add-App-Restricted-Authentication
NPA-4599: Added App Restricted Authentication
2 parents d4d16a0 + d715817 commit 2dc8d18

File tree

9 files changed

+81
-17
lines changed

9 files changed

+81
-17
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[flake8]
22
max-line-length=120
3+
per-file-ignores=proxies/live/apiproxy/resources/*:F821
34
exclude = .git,__pycache__,dist,.venv/*,node_modules/*,utils/*,tests/.venv/*

manifest_template.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ apigee:
9494
scopes: # Step 1: Configured product to include scopes
9595
- 'urn:nhsd:apim:user-nhs-login:P9:{{ SERVICE_NAME }}'
9696
- 'urn:nhsd:apim:user-nhs-id:aal3:{{ SERVICE_NAME }}'
97+
- 'urn:nhsd:apim:app:level3:{{ SERVICE_NAME }}'
9798
specs:
9899
- name: {{ NAME }}
99100
path: {{ SERVICE_NAME }}.json

proxies/live/apiproxy/policies/AssignMessage.AddUserAuthHeaders.xml renamed to proxies/live/apiproxy/policies/AssignMessage.AddAuthHeaders.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<AssignMessage async="false" continueOnError="false" enabled="true" name="AddUserAuthHeaders">
3-
<DisplayName>Add User Auth Headers</DisplayName>
2+
<AssignMessage async="false" continueOnError="false" enabled="true" name="AddAuthHeaders">
3+
<DisplayName>AddAuthHeaders</DisplayName>
44
<Add>
55
<Headers>
66
<Header name="accesstoken.auth_level">{toUpperCase(accesstoken.auth_level)}</Header>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Script async="false" continueOnError="false" enabled="true" name="CheckAppEnabledEndpoint">
3+
<DisplayName>CheckAppEnabledEndpoint</DisplayName>
4+
<Properties/>
5+
<ResourceURL>py://check-app-enabled-endpoint.py</ResourceURL>
6+
</Script>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Script async="false" continueOnError="false" enabled="true" name="CheckUserEnabledEndpoint">
3+
<DisplayName>CheckUserEnabledEndpoint</DisplayName>
4+
<Properties/>
5+
<ResourceURL>py://check-user-enabled-endpoint.py</ResourceURL>
6+
</Script>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--Step 2: Adding VerifyAccessToken policy to your proxy-->
22
<OAuthV2 async="false" continueOnError="false" enabled="true" name="VerifyAccessTokenUser">
33
<Operation>VerifyAccessToken</Operation>
4-
<Scopes>urn:nhsd:apim:user-nhs-login:P9:validated-relationships-service-api urn:nhsd:apim:user-nhs-id:aal3:validated-relationships-service-api</Scopes>
4+
<Scopes>urn:nhsd:apim:app:level3:validated-relationships-service-api urn:nhsd:apim:user-nhs-login:P9:validated-relationships-service-api urn:nhsd:apim:user-nhs-id:aal3:validated-relationships-service-api</Scopes>
55
</OAuthV2>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
path_suffix = flow.getVariable("proxy.pathsuffix").lower()
2+
request_verb = flow.getVariable("request.verb").lower()
3+
4+
requested_endpoint = (path_suffix, request_verb)
5+
6+
7+
auth_forbidden = requested_endpoint in [
8+
("/fhir/r4/relatedperson", "get"),
9+
("/fhir/r4/questionnaireresponse", "post"),
10+
]
11+
12+
flow.setVariable("app_auth_forbidden", auth_forbidden)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
auth_level = flow.getVariable("accesstoken.auth_level").lower()
2+
path_suffix = flow.getVariable("proxy.pathsuffix").lower()
3+
request_verb = flow.getVariable("request.verb").lower()
4+
5+
requested_resource = (path_suffix, request_verb)
6+
7+
if auth_level == "p9":
8+
blocked_resources = [("/fhir/r4/consent", "post"), ("/fhir/r4/consent", "patch")]
9+
elif auth_level == "all3":
10+
blocked_resources = [("/fhir/r4/questionnaireresponse", "post")]
11+
else:
12+
blocked_resources = []
13+
14+
auth_forbidden = requested_resource in blocked_resources
15+
16+
flow.setVariable("user_auth_forbidden", auth_forbidden)

proxies/live/apiproxy/targets/target.xml

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,6 @@
1414
<Step>
1515
<Name>AddProxyURL</Name>
1616
</Step>
17-
<Step>
18-
<Name>DecodeAccessTokenJWT</Name>
19-
</Step>
20-
<Step>
21-
<Name>AddUserAuthHeaders</Name>
22-
</Step>
23-
<Step>
24-
<Name>RaiseFault.403Forbidden</Name>
25-
<Condition>accesstoken.auth_level != "aal3" and proxy.pathsuffix = "/FHIR/R4/Consent" and request.verb = "POST"</Condition>
26-
</Step>
27-
<Step>
28-
<Name>RaiseFault.403Forbidden</Name>
29-
<Condition>accesstoken.auth_level != "p9" and (proxy.pathsuffix != "/FHIR/R4/Consent" or request.verb != "POST")</Condition>
30-
</Step>
3117
<Step>
3218
<Name>RaiseFault.415UnsupportedMediaType</Name>
3319
<Condition>request.verb = "POST" and request.header.Content-Type != "application/fhir+json" and request.header.Content-Type != "application/fhir+json; charset=utf-8"</Condition>
@@ -37,6 +23,42 @@
3723
</Step>
3824
</Request>
3925
</PreFlow>
26+
<Flows>
27+
<Flow name="App Restricted">
28+
<Condition>accesstoken.auth_type = "app"</Condition>
29+
<Request>
30+
<Step>
31+
<Name>CheckAppEnabledEndpoint</Name>
32+
</Step>
33+
<Step>
34+
<Name>RaiseFault.403Forbidden</Name>
35+
<Condition>app_auth_forbidden = true</Condition>
36+
</Step>
37+
<Step>
38+
<Name>AddAuthHeaders</Name>
39+
</Step>
40+
</Request>
41+
</Flow>
42+
<Flow name ="User Restricted">
43+
<Condition>accesstoken.auth_type = "user"</Condition>
44+
<Request>
45+
<Step>
46+
<Name>CheckUserEnabledEndpoint</Name>
47+
</Step>
48+
<Step>
49+
<Name>RaiseFault.403Forbidden</Name>
50+
<Condition>user_auth_forbidden = true</Condition>
51+
</Step>
52+
<Step>
53+
<Name>DecodeAccessTokenJWT</Name>
54+
</Step>
55+
<Step>
56+
<Name>AddAuthHeaders</Name>
57+
</Step>
58+
</Request>
59+
</Flow>
60+
</Flows>
61+
4062
<PostFlow>
4163
<Response>
4264
<Step>

0 commit comments

Comments
 (0)