Skip to content
This repository was archived by the owner on Jun 12, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/oidcendpoint/jwt_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
from typing import Optional

from cryptojwt import JWT
from cryptojwt.jws.exception import JWSException

from oidcendpoint.exception import ToOld
from oidcendpoint.token_handler import Token
from oidcendpoint.token_handler import is_expired
from oidcendpoint.token_handler import UnknownToken
from oidcendpoint.user_info import scope2claims


Expand Down Expand Up @@ -94,7 +96,10 @@ def info(self, token):
:return: tuple of token type and session id
"""
verifier = JWT(key_jar=self.key_jar, allowed_sign_algs=[self.alg])
_payload = verifier.unpack(token)
try:
_payload = verifier.unpack(token)
except JWSException:
raise UnknownToken()

if is_expired(_payload["exp"]):
raise ToOld("Token has expired")
Expand Down
90 changes: 18 additions & 72 deletions src/oidcendpoint/oauth2/introspection.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Implements RFC7662"""
import logging

from cryptojwt import JWT
from cryptojwt.jws.jws import factory
from oidcmsg import oauth2
from oidcmsg.time_util import utc_time_sans_frac

Expand All @@ -11,18 +9,6 @@
LOGGER = logging.getLogger(__name__)


def before(t1, t2, range):
if t1 < (t2 - range):
return True
return False


def after(t1, t2, range):
if t1 > (t2 + range):
return True
return False


class Introspection(Endpoint):
"""Implements RFC 7662"""

Expand All @@ -49,49 +35,30 @@ def get_client_id_from_token(self, endpoint_context, token, request=None):
sinfo = endpoint_context.sdb[token]
return sinfo["authn_req"]["client_id"]

def do_jws(self, token):
_jwt = JWT(key_jar=self.endpoint_context.keyjar)

def _introspect(self, token):
try:
_jwt_info = _jwt.unpack(token)
except Exception as err:
return None

return _jwt_info

def do_access_token(self, token):
try:
_info = self.endpoint_context.sdb[token]
info = self.endpoint_context.sdb[token]
except KeyError:
return None

_revoked = _info.get("revoked", False)
if _revoked:
# Make sure that the token is an access_token or a refresh_token
if token not in info.get("access_token") and token != info.get(
"refresh_token"
):
return None

_eat = _info.get("expires_at")
if _eat < utc_time_sans_frac():
eat = info.get("expires_at")
if eat and eat < utc_time_sans_frac():
return None

if _info: # Now what can be returned ?
_ret = {
"sub": _info["sub"],
"client_id": _info["client_id"],
"token_type": "bearer",
"iss": self.endpoint_context.issuer
}
_authn = _info.get("authn_event")
if _authn:
_ret["authn_info"] = _authn["authn_info"]
_ret["authn_time"] = _authn["authn_time"]

_scope = _info.get("scope")
if not _scope:
_ret["scope"] = " ".join(_info["authn_req"]["scope"])

return _ret
else:
return _info
if info: # Now what can be returned ?
ret = info.to_dict()
ret["iss"] = self.endpoint_context.issuer

if "scope" not in ret:
ret["scope"] = " ".join(info["authn_req"]["scope"])

return ret

def process_request(self, request=None, **kwargs):
"""
Expand All @@ -107,29 +74,8 @@ def process_request(self, request=None, **kwargs):
_token = _introspect_request["token"]
_resp = self.response_cls(active=False)

if factory(_token):
_info = self.do_jws(_token)
if _info is None:
return {"response_args": _resp}
_now = utc_time_sans_frac()

# Time checks
if "exp" in _info:
if after(_now, _info["exp"], self.offset):
return {"response_args": _resp}
if 'iat' in _info:
if after(_info["iat"], _now, self.offset):
return {"response_args": _resp}
if 'nbf' in _info:
if before(_now, _info["nbf"], self.offset):
return {"response_args": _resp}
else:
# A non-jws access token
_info = self.do_access_token(_token)
if _info is None:
return {"response_args": _resp}

if not _info:
_info = self._introspect(_token)
if _info is None:
return {"response_args": _resp}

if "release" in self.kwargs:
Expand Down
4 changes: 2 additions & 2 deletions src/oidcendpoint/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,8 @@ def revoke_session(self, sid="", token=""):
_sinfo = self[sid]
for token_type in self.handler.keys():
_sinfo.pop(token_type, None)

self.update(sid, revoked=True)
_sinfo["revoked"] = True
self[sid] = _sinfo

def get_client_id_for_session(self, sid):
return self[sid]["client_id"]
Expand Down
4 changes: 3 additions & 1 deletion src/oidcendpoint/token_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from cryptojwt.key_jar import init_key_jar
from cryptojwt.utils import as_bytes
from cryptojwt.utils import as_unicode
from cryptojwt.exception import BadSyntax
from oidcmsg.time_util import time_sans_frac

from oidcendpoint import rndstr
Expand Down Expand Up @@ -218,7 +219,8 @@ def info(self, item, order=None):
for typ in order:
try:
return self.handler[typ].info(item)
except (KeyError, WrongTokenType, InvalidToken, UnknownToken):
except (KeyError, WrongTokenType, InvalidToken, UnknownToken,
BadSyntax):
pass

logger.info("Unknown token format")
Expand Down
Loading