Skip to content

Commit

Permalink
PBENCH-865 First pass at implementing OIDC token decode framework (#2942
Browse files Browse the repository at this point in the history
)

Includes the IDP token management sequence diagram

PBENCH-865
  • Loading branch information
npalaska authored Sep 16, 2022
1 parent 229cec5 commit b938d0d
Show file tree
Hide file tree
Showing 15 changed files with 549 additions and 16 deletions.
104 changes: 104 additions & 0 deletions docs/user_authentication/third_party_token_management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

```sequence {theme: 'simple'}
title Third-party Token Management
participant Pbench-Server
participant Browser
participant Identity-Broker
participant Identity-Provider
autonumber 1
activate Browser #red
rbox over Browser: Dashboard
Browser->Pbench-Server: GET Pbench client ID
Pbench-Server->Browser: 200 Response
note right of Pbench-Server:{identity_broker_auth_URI: <auth_URI>\nclient_id: <pbench_client_id>\nclient_secret: <pbench_client_secret> # optional\n}
note over Browser:User clicks login
abox over Browser: Dashboard instructs the browser to \nload identity broker authentication page \nurl that was supplied by the Pbench-server.
deactivate Browser
Browser->Identity-Broker:GET identity broker auth URI\n(Authentication Request)
note right of Browser:GET request:\n<identity_broker_auth_URI>\n?client_id=<pbench_client_id>\n&response_type=code\n&redirect_uri=<dashboard_URI>\n&scope=openid
Identity-Broker->Browser: 200 Response
activate Browser #blue
rbox over Browser: Identity-Broker
note over Browser:User selects an identity provider from the list
abox over Browser:Identity broker instructs the browser to \nload identity provider authentication page
deactivate Browser
Browser->Identity-Provider:GET identity provider auth page
note right of Browser:GET request:\n<identity_provider_auth_URI>\n?client_id=<client_id as registered on identity provider>\n&response_type=code\n&redirect_uri=<identity_broker_URI>\n&scope=openid
Identity-Provider->Browser:303 Response\n(Redirect to identity provider auth page)
Browser->Identity-Provider:GET request auth Page
Browser<-Identity-Provider:200 Response
activate Browser #green
rbox over Browser: Identity-Provider
note over Browser:User challenge credentials and consent
abox over Browser:Identity provider instructs the browser to \nsend the request and load the response
deactivate Browser
Browser->Identity-Provider: GET/POST authentication request
Identity-Provider->Browser: 302/303 Response
note left of Identity-Provider:Redirect Location:\n<identity_broker_URI>\n?code=<auth_code>\n&state=<session_state_id>
Identity-Broker<-Browser:GET Redirect location (identity broker URI)
note over Identity-Broker:Identity federation\na. Checks the validity of response from the identity provider\nb. Imports and creates user identity from the token\nc. Links the user identity with the identity provider
Identity-Broker->Browser:302 Authentication Response\n(Redirect back to Pbench dashboard)
note left of Identity-Broker:Redirect Location:\n<dashboard_URI>\n?code=<identity_broker_auth_code>\n&state=<session_state_id>
Browser->Pbench-Server: GET Pbench-dashboard redirect location
Pbench-Server->Browser: 200 Response
activate Browser #red
rbox over Browser: Dashboard
Browser->Identity-Broker:POST Request to token endpoint
note right of Browser:POST request:\npost <identity_broker_token_endpoint>\npayload:\n{code: <identity_broker_auth_code>\nclient_id: <pbench_client_id>\nredirect_uri: <dashboard_URI>\n}
Identity-Broker->Browser: 200 Token Response
note left of Identity-Broker:token response:\n{\n access_token: <identity_broker_access_token>,\n expires_in: <number_of_seconds>,\n refresh_expires_in: <number_of_seconds>,\n refresh_token: <refresh_token>,\n token_type: "Bearer",\n id_token: <id_token>\n session_state: <session_id>,\n scope: <openid_email_profile>\n}
==Authorization setup complete; the steps below may be repeated to issue a series of requests==
Browser->Pbench-Server: POST /api/v1/<restricted_endpoint> request (Bearer: Pbench access token)
note over Pbench-Server:Validation and identity extraction\nfrom the Pbench token
alt Authenticated user is authorized for resource
Pbench-Server->Browser: 200 /api/v1/<restricted_endpoint> response
else Authenticated user is not authorized for resource
Pbench-Server->Browser:403 /api/v1/<restricted_endpoint> response
else Authorization token expired or invalid
Pbench-Server->Browser:401 /api/v1/<restricted_endpoint> response
end
space
deactivate Browser
destroysilent Pbench-Server
destroysilent Browser
destroysilent Identity-Broker
destroysilent Identity-Provider
```
2 changes: 1 addition & 1 deletion lib/pbench/server/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from pbench.common.exceptions import BadConfig, ConfigFileNotSpecified
from pbench.common.logger import get_pbench_logger
from pbench.server import PbenchServerConfig
from pbench.server.api.auth import Auth
from pbench.server.api.resources.datasets_daterange import DatasetsDateRange
from pbench.server.api.resources.datasets_inventory import DatasetsInventory
from pbench.server.api.resources.datasets_list import DatasetsList
Expand All @@ -39,6 +38,7 @@
from pbench.server.api.resources.server_configuration import ServerConfiguration
from pbench.server.api.resources.upload_api import Upload
from pbench.server.api.resources.users_api import Login, Logout, RegisterUser, UserAPI
from pbench.server.auth.auth import Auth
from pbench.server.database import init_db
from pbench.server.database.database import Database

Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/server/api/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from sqlalchemy.orm.query import Query

from pbench.server import JSON, JSONOBJECT, JSONVALUE, PbenchServerConfig
from pbench.server.api.auth import Auth
from pbench.server.auth.auth import Auth
from pbench.server.database.models.datasets import (
Dataset,
DatasetNotFound,
Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/server/api/resources/datasets_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from flask.wrappers import Request, Response

from pbench.server import PbenchServerConfig
from pbench.server.api.auth import Auth
from pbench.server.api.resources import (
API_AUTHORIZATION,
API_METHOD,
Expand All @@ -20,6 +19,7 @@
ParamType,
Schema,
)
from pbench.server.auth.auth import Auth
from pbench.server.database.models.datasets import (
Metadata,
MetadataBadValue,
Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/server/api/resources/query_apis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import requests

from pbench.server import JSON, PbenchServerConfig
from pbench.server.api.auth import Auth
from pbench.server.api.resources import (
API_AUTHORIZATION,
API_METHOD,
Expand All @@ -27,6 +26,7 @@
SchemaError,
UnauthorizedAccess,
)
from pbench.server.auth.auth import Auth
from pbench.server.database.models.datasets import Dataset
from pbench.server.database.models.template import Template
from pbench.server.database.models.users import User
Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/server/api/resources/upload_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import humanize

from pbench.common.utils import Cleanup, validate_hostname
from pbench.server.api.auth import Auth
from pbench.server.auth.auth import Auth
from pbench.server.database.models.datasets import (
Dataset,
DatasetDuplicate,
Expand Down
9 changes: 6 additions & 3 deletions lib/pbench/server/api/resources/users_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import timedelta
from http import HTTPStatus
from typing import NamedTuple

Expand All @@ -8,7 +9,7 @@
import jwt
from sqlalchemy.exc import IntegrityError, SQLAlchemyError

from pbench.server.api.auth import Auth
from pbench.server.auth.auth import Auth
from pbench.server.database.models.active_tokens import ActiveTokens
from pbench.server.database.models.server_config import ServerConfig
from pbench.server.database.models.users import User
Expand Down Expand Up @@ -150,7 +151,8 @@ def __init__(self, config, logger, auth):
def post(self):
"""
Post request for logging in user.
The user is allowed to re-login multiple times and each time a new valid auth token will be provided
The user is allowed to re-login multiple times and each time a new
valid auth token will be returned.
This requires a JSON data with required user metadata fields
{
Expand Down Expand Up @@ -210,7 +212,8 @@ def post(self):

try:
auth_token = self.auth.encode_auth_token(
self.token_expire_duration, user.id
time_delta=timedelta(minutes=int(self.token_expire_duration)),
user_id=user.id,
)
except (
jwt.InvalidIssuer,
Expand Down
Loading

0 comments on commit b938d0d

Please sign in to comment.