Skip to content

Commit

Permalink
Showing 5 changed files with 57 additions and 13 deletions.
5 changes: 5 additions & 0 deletions auth/api/iam/api.go
Original file line number Diff line number Diff line change
@@ -170,18 +170,21 @@ func (r Wrapper) IntrospectAccessToken(_ context.Context, request IntrospectAcce
// Validate token
if request.Body.Token == "" {
// Return 200 + 'Active = false' when token is invalid or malformed
log.Logger().Debug("IntrospectAccessToken: missing token")
return IntrospectAccessToken200JSONResponse{}, nil
}

token := AccessToken{}
if err := r.accessTokenStore().Get(request.Body.Token, &token); err != nil {
// Return 200 + 'Active = false' when token is invalid or malformed
log.Logger().Debug("IntrospectAccessToken: failed to get token from store")
return IntrospectAccessToken200JSONResponse{}, err
}

if token.Expiration.Before(time.Now()) {
// Return 200 + 'Active = false' when token is invalid or malformed
// can happen between token expiration and pruning of database
log.Logger().Debug("IntrospectAccessToken: token is expired")
return IntrospectAccessToken200JSONResponse{}, nil
}

@@ -215,12 +218,14 @@ func (r Wrapper) IntrospectAccessToken(_ context.Context, request IntrospectAcce
var err error
response.PresentationDefinition, err = toAnyMap(token.PresentationDefinition)
if err != nil {
log.Logger().WithError(err).Error("IntrospectAccessToken: failed to marshal presentation definition")
return IntrospectAccessToken200JSONResponse{}, err
}

// set presentation submission if in token
response.PresentationSubmission, err = toAnyMap(token.PresentationSubmission)
if err != nil {
log.Logger().WithError(err).Error("IntrospectAccessToken: failed to marshal presentation submission")
return IntrospectAccessToken200JSONResponse{}, err
}
return response, nil
1 change: 1 addition & 0 deletions e2e-tests/oauth-flow/rfc021/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ services:
- "../../tls-certs/nodeA-certificate.pem:/etc/nginx/ssl/key.pem:ro"
- "../../tls-certs/truststore.pem:/etc/nginx/ssl/truststore.pem:ro"
- "./node-A/html:/etc/nginx/html:ro"
- "./node-A/oauth2.js:/etc/nginx/oauth2.js:ro"
nodeB-backend:
image: "${IMAGE_NODE_B:-nutsfoundation/nuts-node:master}"
ports:
23 changes: 19 additions & 4 deletions e2e-tests/oauth-flow/rfc021/node-A/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
load_module /usr/lib/nginx/modules/ngx_http_js_module.so;

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
js_import oauth2.js;
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
@@ -43,5 +44,19 @@ http {
proxy_set_header X-Ssl-Client-Cert $ssl_client_escaped_cert;
proxy_pass http://nodeA-backend;
}

# check access via token introspection as described by https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/
location /resource {
js_content oauth2.introspectAccessToken;
}

# Location in javascript subrequest.
# this is needed to set headers and method
location /_oauth2_send_request {
internal;
proxy_method POST;
proxy_set_header Content-Type "application/x-www-form-urlencoded";
proxy_pass http://nodeA-backend/internal/auth/v2/accesstoken/introspect;
}
}
}
23 changes: 23 additions & 0 deletions e2e-tests/oauth-flow/rfc021/node-A/oauth2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// # check access via token introspection as described by https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/
function introspectAccessToken(r) {
// strip the first 8 chars
var token = "token=" + r.headersIn['Authorization'].substring(7);
// make a subrequest to the introspection endpoint
r.subrequest("/_oauth2_send_request",
{ method: "POST", body: token },
function(reply) {
if (reply.status == 200) {
var introspection = JSON.parse(reply.responseBody);
if (introspection.active) {
r.return(200, "OK");
} else {
r.return(403, "Unauthorized");
}
} else {
r.return(500, "Internal Server Error");
}
}
);
}

export default { introspectAccessToken };
18 changes: 9 additions & 9 deletions e2e-tests/oauth-flow/rfc021/run-test.sh
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ echo "------------------------------------"
echo "Starting Docker containers..."
echo "------------------------------------"
docker compose up -d
docker compose up --wait nodeA-backend nodeB
docker compose up --wait nodeA nodeA-backend nodeB nodeB-backend

echo "------------------------------------"
echo "Registering vendors..."
@@ -66,14 +66,14 @@ fi
echo "------------------------------------"
echo "Retrieving data..."
echo "------------------------------------"
#RESPONSE=$(docker compose exec nodeB curl --insecure --cert /etc/nginx/ssl/server.pem --key /etc/nginx/ssl/key.pem https://nodeA:443/ping -H "Authorization: bearer $(cat ./node-B/data/accesstoken.txt)" -v)
#if echo $RESPONSE | grep -q "pong"; then
# echo "success!"
#else
# echo "FAILED: Could not ping node-A" 1>&2
# echo $RESPONSE
# exitWithDockerLogs 1
#fi
RESPONSE=$(docker compose exec nodeB curl --http1.1 --insecure --cert /etc/nginx/ssl/server.pem --key /etc/nginx/ssl/key.pem https://nodeA:443/resource -H "Authorization: bearer $(cat ./node-B/data/accesstoken.txt)" -v)
if echo $RESPONSE | grep -q "OK"; then
echo "success!"
else
echo "FAILED: Could not get resource from node-A" 1>&2
echo $RESPONSE
exitWithDockerLogs 1
fi

echo "------------------------------------"
echo "Stopping Docker containers..."

0 comments on commit 788f923

Please sign in to comment.