-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from QuanMPhm/42/oidc_auth
Fixed OIDC authentication for SCIM endpoints
- Loading branch information
Showing
14 changed files
with
194 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
name: test-py39-functional-scim-auth | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
test-scim-auth: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Check out code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.9 | ||
|
||
- name: Run keycloak container | ||
run: | | ||
./ci/run_keycloak.sh | ||
- name: Install Coldfront and plugin | ||
run: | | ||
./ci/setup.sh | ||
- name: Run SCIM authentication functional test | ||
run: | | ||
./ci/run_functional_test_scim_auth.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# For onbarding-tools | ||
export KEYCLOAK_USERNAME=admin | ||
export KEYCLOAK_PASSWORD=nomoresecret | ||
export KEYCLOAK_URL="http://localhost:8080" | ||
export OIDC_CLIENT_ID=coldfront | ||
export OIDC_CLIENT_SECRET=nomoresecret | ||
export HORIZON_URL="http://foo" | ||
|
||
# For coldfront oidc plugin | ||
export DJANGO_SETTINGS_MODULE="local_settings" | ||
export PLUGIN_AUTH_OIDC=True | ||
export OIDC_RP_CLIENT_ID="coldfront" | ||
export OIDC_RP_CLIENT_SECRET='nomoresecret' | ||
export OIDC_OP_AUTHORIZATION_ENDPOINT="http://localhost:8080/realms/master/protocol/openid-connect/auth" | ||
export OIDC_OP_TOKEN_ENDPOINT="http://localhost:8080/realms/master/protocol/openid-connect/token" | ||
export OIDC_OP_USER_ENDPOINT="http://localhost:8080/realms/master/protocol/openid-connect/userinfo" | ||
export OIDC_RP_SIGN_ALGO='RS256' | ||
export OIDC_OP_JWKS_ENDPOINT="http://localhost:8080/realms/master/protocol/openid-connect/certs" | ||
|
||
coldfront test coldfront_plugin_api.tests.functional.test_scim_auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
set -xe | ||
|
||
sudo docker run -d --name keycloak \ | ||
-e KEYCLOAK_ADMIN=admin \ | ||
-e KEYCLOAK_ADMIN_PASSWORD=nomoresecret \ | ||
-p 8080:8080 \ | ||
-p 8443:8443 \ | ||
quay.io/keycloak/keycloak:latest start-dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import os | ||
import logging | ||
|
||
from django_scim.middleware import SCIMAuthCheckMiddleware | ||
from mozilla_django_oidc.contrib.drf import OIDCAuthentication | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class SCIMColdfrontAuthCheckMiddleware(SCIMAuthCheckMiddleware): | ||
def process_request(self, request): | ||
if not request.user or not request.user.is_authenticated: | ||
# django-scim2 does not use by default the DRF backend of mozilla-django-oidc, | ||
# and therefore does not support authentication with bearer tokens, only | ||
# session cookies. We manually call `authenticate()` on the DRF backend if | ||
# the user is not already authenticated, and if OIDC authentication is enabled. | ||
if os.getenv("PLUGIN_AUTH_OIDC") == "True": | ||
if user_tuple := OIDCAuthentication().authenticate(request): | ||
request.user = user_tuple[0] | ||
return super().process_request(request) |
File renamed without changes.
Empty file.
65 changes: 65 additions & 0 deletions
65
src/coldfront_plugin_api/tests/functional/test_scim_auth.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import os | ||
|
||
from django.test import Client | ||
|
||
|
||
from coldfront_plugin_api.tests.functional import utils | ||
from coldfront_plugin_api.tests.base import TestBase | ||
|
||
|
||
class TestAuthOIDC(TestBase): | ||
@classmethod | ||
def setUpClass(self): | ||
super().setUpClass() | ||
self.kc_client = utils.UpdatedKeycloakClient() | ||
# Only initialize Coldfront client if running in Github action | ||
if os.getenv("CI") == "true": | ||
self.kc_client.create_client( | ||
"master", | ||
"coldfront", | ||
"nomoresecret", | ||
["http://foo/signup/oidc_redirect_uri"], | ||
) | ||
self.kc_client.create_user("master", "[email protected]", "staff", "staff") | ||
self.kc_client.create_user("master", "[email protected]", "user", "user") | ||
|
||
def setUp(self): | ||
super().setUp() | ||
self.staff_user = self.new_user("[email protected]") | ||
self.normal_user = self.new_user("[email protected]") | ||
|
||
self.staff_user.is_staff = True | ||
self.staff_user.save() | ||
|
||
def test_oidc_authenticated(self): | ||
# Test for both staff and normal authenticated users | ||
def impersonate_and_get_endpoint( | ||
user_to_impersonate, endpoint_url, expected_status_code | ||
): | ||
user_token = self.kc_client.impersonate_access_token(user_to_impersonate) | ||
|
||
cf_client = Client() | ||
r = cf_client.get( | ||
endpoint_url, | ||
HTTP_AUTHORIZATION=f"Bearer {user_token}", | ||
) | ||
self.assertEqual(r.status_code, expected_status_code) | ||
|
||
for endpoint_url in [ | ||
"/api/scim/v2/Users", | ||
"/api/scim/v2/Groups", | ||
"/api/allocations", | ||
]: | ||
impersonate_and_get_endpoint(self.staff_user.username, endpoint_url, 200) | ||
impersonate_and_get_endpoint(self.normal_user.username, endpoint_url, 403) | ||
|
||
def test_oidc_unauthenticated(self): | ||
# Test for unauthenticated user case | ||
cf_client = Client() | ||
for endpoint_url in [ | ||
"/api/scim/v2/Users", | ||
"/api/scim/v2/Groups", | ||
"/api/allocations", | ||
]: | ||
r = cf_client.get(endpoint_url) | ||
self.assertEqual(r.status_code, 401) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import urllib | ||
import requests | ||
|
||
from onboarding_tools.keycloak import KeycloakClient | ||
from onboarding_tools import settings | ||
|
||
|
||
class UpdatedKeycloakClient(KeycloakClient): | ||
@staticmethod | ||
def construct_url(realm, path): | ||
return f"{settings.KEYCLOAK_URL}/admin/realms/{realm}/{path}" | ||
|
||
@property | ||
def url_base(self): | ||
return f"{settings.KEYCLOAK_URL}/admin/realms" | ||
|
||
@staticmethod | ||
def auth_endpoint(realm): | ||
return f"{settings.KEYCLOAK_URL}/realms/{realm}/protocol/openid-connect/auth" | ||
|
||
@staticmethod | ||
def token_endpoint(realm): | ||
return f"{settings.KEYCLOAK_URL}/realms/{realm}/protocol/openid-connect/token" | ||
|
||
def impersonate_access_token(self, user): | ||
user_session = requests.session() | ||
user_session.cookies.update(self.impersonate(user).cookies) | ||
params = { | ||
"response_mode": "fragment", | ||
"response_type": "token", | ||
"client_id": settings.OIDC_CLIENT_ID, | ||
"client_secret": settings.OIDC_CLIENT_SECRET, | ||
"redirect_uri": f"{settings.HORIZON_URL}/signup/oidc_redirect_uri", | ||
"scope": "openid profile email", | ||
} | ||
response = user_session.get( | ||
self.auth_endpoint("master"), params=params, allow_redirects=False | ||
) | ||
redirect = response.headers["Location"] | ||
token = urllib.parse.parse_qs(redirect)["access_token"][0] | ||
return token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
git+https://github.com/nerc-project/coldfront-plugin-cloud@main#egg=coldfront_plugin_cloud | ||
git+https://github.com/CCI-MOC/onboarding-tools@master#egg=onboarding_tools |