Skip to content
11 changes: 11 additions & 0 deletions example/plugins/microservices/custom_routing.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module: satosa.micro_services.custom_routing.DecideIfRequesterIsAllowed
name: RequesterDecider
config:
rules:
target_entity_id1:
allow: ["requester1", "requester2"]
target_entity_id2:
deny: ["requester3"]
target_entity_id3:
allow: ["requester1"]
deny: ["*"]
9 changes: 9 additions & 0 deletions example/plugins/microservices/filter_requester.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Requester whitelist: this microservice cannot be used for blacklisting
config:
allow:
# this list must not be empty. Use '*' to allow all requesters
- https://sp1.test.wpv.portalverbund.at/sp.xml
- https://sp3.test.wpv.portalverbund.at/sp.xml
- https://sp4.test.wpv.portalverbund.at/sp.xml
module: satosa.micro_services.filter_requester.FilterRequester
name: FilterRequester
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module: satosa.micro_services.redirect_url.RedirectUrlRequest
name: RedirectUrlRequest
config:
db_encryption_key: "WQpuhOELqGAs/ct2mujCqw"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module: satosa.micro_services.redirect_url.RedirectUrlResponse
name: RedirectUrlResponse
config:
db_encryption_key: "WQpuhOELqGAs/ct2mujCqw" # must be same in redirect_url_request.yaml
redirect_attr_name: WkisRedirect
redir_entityid: http://wkis.qss.wko.at/adfs/services/trust
36 changes: 36 additions & 0 deletions example/plugins/microservices/simpleconsent.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# this file contains secret keys. Protect file or insert values from environment

module: satosa.micro_services.simpleconsent.SimpleConsent
name: SimpleConsent
config:
consent_cookie_name: SATOSA_CONSENTID
consent_attr_not_displayed:
- addr_country
- authenticationClass
- possibleroles
- registrationClassOrg
- registrationClassUser
- wkis_roleextendeddescription
- wkis_roletypeid
consent_attrname_display:
uid: UserID
displayname: Anzeigename
givenname: Vorname
gln: "GLN der Firma"
mail: E-Mailadresse
name: Vor+Familienname
surname: Familienname
wkis_roledescription: "WKO Mitglied"
consent_service_api_auth:
userid: admin
password: adminadmin
id_hash_alg: md5 # md5 is shorter than sha-224, but may be missing in (rare) FIPS-compliant C-Python
# shard secret: configure same ASCII-value in proxy and consent app
PROXY_HMAC_KEY: "your random key (-> `openssh rand -base64 30`)"
request_consent_url: https://consent.example.org/request_consent
self_entityid: satosa.vnet/idp_proxy.xml
# consent display page: translate SP entityIDs to human readable names
# (work around, as metadata is not available in the micro service)
sp_entityid_names:
https://sp1.test.wpv.portalverbund.at/sp.xml: "Test SP1"
verify_consent_url: https://consent.example.org/has_consent
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"pystache"
],
extras_require={
"ldap": ["ldap3"]
"ldap": ["ldap3"],
"redirecturl": ["redis"],
},
zip_safe=False,
classifiers=[
Expand Down
2 changes: 1 addition & 1 deletion src/satosa/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __init__(self, auth_callback_func, internal_attributes, base_url, name):
self.base_url = base_url
self.name = name

def start_auth(self, context, internal_request):
def start_auth(self, context, internal_request, **kwargs):
"""
This is the start up function of the backend authorization.

Expand Down
4 changes: 2 additions & 2 deletions src/satosa/backends/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
outgoing, internal_attributes, config, base_url, name, 'github',
'id')

def start_auth(self, context, internal_request, get_state=stateID):
def start_auth(self, context, internal_request, get_state=stateID, **kwargs):
"""
:param get_state: Generates a state to be used in authentication call

Expand Down Expand Up @@ -75,7 +75,7 @@ def auth_info(self, requrest):
UNSPECIFIED, None,
self.config['server_info']['authorization_endpoint'])

def _authn_response(self, context):
def _authn_response(self, context, **kwargs):
state_data = context.state[self.name]
aresp = self.consumer.parse_response(
AuthorizationResponse, info=json.dumps(context.request))
Expand Down
4 changes: 2 additions & 2 deletions src/satosa/backends/linkedin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
outgoing, internal_attributes, config, base_url, name, 'linkedin',
'id')

def start_auth(self, context, internal_request, get_state=stateID):
def start_auth(self, context, internal_request, get_state=stateID, **kwargs):
"""
:param get_state: Generates a state to be used in authentication call

Expand Down Expand Up @@ -76,7 +76,7 @@ def auth_info(self, requrest):
UNSPECIFIED, None,
self.config['server_info']['authorization_endpoint'])

def _authn_response(self, context):
def _authn_response(self, context, **kwargs):
state_data = context.state[self.name]
aresp = self.consumer.parse_response(
AuthorizationResponse, info=json.dumps(context.request))
Expand Down
4 changes: 2 additions & 2 deletions src/satosa/backends/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name, extern
response_type=self.config["response_type"])
self.consumer.client_secret = self.config["client_secret"]

def start_auth(self, context, internal_request, get_state=stateID):
def start_auth(self, context, internal_request, get_state=stateID, **kwargs):
"""
See super class method satosa.backends.base#start_auth
:param get_state: Generates a state to be used in the authentication call.
Expand Down Expand Up @@ -118,7 +118,7 @@ def _verify_state(self, resp, state_data, state):
"Missing or invalid state [%s] in response!" %
received_state)

def _authn_response(self, context):
def _authn_response(self, context, **kwargs):
"""
Handles the authentication response from the AS.

Expand Down
4 changes: 2 additions & 2 deletions src/satosa/backends/openid_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def __init__(self, auth_callback_func, internal_attributes, config, base_url, na
if "response_type" not in config["client"]["auth_req_params"]:
config["auth_req_params"]["response_type"] = "code"

def start_auth(self, context, request_info):
def start_auth(self, context, request_info, **kwargs):
"""
See super class method satosa.backends.base#start_auth
:type context: satosa.context.Context
Expand Down Expand Up @@ -167,7 +167,7 @@ def _get_userinfo(self, state, context):
self._check_error_response(userinfo_resp, context)
return userinfo_resp.to_dict()

def response_endpoint(self, context, *args):
def response_endpoint(self, context, *args, **kwargs):
"""
Handles the authentication response from the OP.
:type context: satosa.context.Context
Expand Down
2 changes: 1 addition & 1 deletion src/satosa/backends/orcid.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def auth_info(self, requrest):
UNSPECIFIED, None,
self.config['server_info']['authorization_endpoint'])

def _authn_response(self, context):
def _authn_response(self, context, **kwargs):
state_data = context.state[self.name]
aresp = self.consumer.parse_response(
AuthorizationResponse, info=json.dumps(context.request))
Expand Down
25 changes: 13 additions & 12 deletions src/satosa/backends/saml2.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
with open(p) as key_file:
self.encryption_keys.append(key_file.read())

def get_idp_entity_id(self, context):
def get_idp_entity_id(self, context, **kwargs):
"""
:type context: satosa.context.Context
:rtype: str | None
Expand Down Expand Up @@ -164,7 +164,7 @@ def get_idp_entity_id(self, context):
)
return entity_id

def start_auth(self, context, internal_req):
def start_auth(self, context, internal_req, **kwargs):
"""
See super class method satosa.backends.base.BackendModule#start_auth

Expand All @@ -184,7 +184,7 @@ def start_auth(self, context, internal_req):

return self.authn_request(context, entity_id)

def disco_query(self, context):
def disco_query(self, context, **kwargs):
"""
Makes a request to the discovery server

Expand Down Expand Up @@ -236,7 +236,7 @@ def construct_requested_authn_context(self, entity_id):

return authn_context

def authn_request(self, context, entity_id):
def authn_request(self, context, entity_id, **kwargs):
"""
Do an authorization request on idp with given entity id.
This is the start of the authorization.
Expand Down Expand Up @@ -294,7 +294,7 @@ def authn_request(self, context, entity_id):
context.state[self.name] = {"relay_state": relay_state}
return make_saml_response(binding, ht_args)

def authn_response(self, context, binding):
def authn_response(self, context, binding, **kwargs):
"""
Endpoint for the idp response
:type context: satosa.context,Context
Expand Down Expand Up @@ -326,11 +326,12 @@ def authn_response(self, context, binding):
raise SATOSAAuthenticationError(context.state, errmsg)
del self.outstanding_queries[req_id]

# check if the relay_state matches the cookie state
if context.state[self.name]["relay_state"] != context.request["RelayState"]:
satosa_logging(logger, logging.DEBUG,
"State did not match relay state for state", context.state)
raise SATOSAAuthenticationError(context.state, "State did not match relay state")
# if the response relay_state exists it must match that from the request
if self.name in context.state and "relay_state" in context.state[self.name]:
if context.state[self.name]["relay_state"] != context.request["RelayState"]:
logger.debug("State did not match relay state for state", extra={'state': context.state})
raise SATOSAAuthenticationError(context.state, "State did not match relay state")
del context.state[self.name]

context.decorate(Context.KEY_BACKEND_METADATA_STORE, self.sp.metadata)
if self.config.get(SAMLBackend.KEY_MEMORIZE_IDP):
Expand All @@ -340,7 +341,7 @@ def authn_response(self, context, binding):
context.state.pop(Context.KEY_FORCE_AUTHN, None)
return self.auth_callback_func(context, self._translate_response(authn_response, context.state))

def disco_response(self, context):
def disco_response(self, context, **kwargs):
"""
Endpoint for the discovery server response

Expand Down Expand Up @@ -406,7 +407,7 @@ def _translate_response(self, response, state):
json.dumps(response.ava, indent=4), state)
return internal_resp

def _metadata_endpoint(self, context):
def _metadata_endpoint(self, context, **kwargs):
"""
Endpoint for retrieving the backend metadata
:type context: satosa.context.Context
Expand Down
2 changes: 1 addition & 1 deletion src/satosa/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def _run_bound_endpoint(self, context, spec):
:return: response
"""
try:
return spec(context)
return spec(context, wsgi_app=self)
except SATOSAAuthenticationError as error:
error.error_id = uuid.uuid4().urn
state = json.dumps(error.state.state_dict, indent=4)
Expand Down
2 changes: 1 addition & 1 deletion src/satosa/frontends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, auth_req_callback_func, internal_attributes, base_url, name):
self.base_url = base_url
self.name = name

def handle_authn_response(self, context, internal_resp):
def handle_authn_response(self, context, internal_resp, **kwargs):
"""
If an authorization has been successful in a backend, this function is called and is
supposed to send an authorization response to the client.
Expand Down
16 changes: 8 additions & 8 deletions src/satosa/frontends/openid_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def _init_authorization_state(self):
return AuthorizationState(HashBasedSubjectIdentifierFactory(sub_hash_salt), authz_code_db, access_token_db,
refresh_token_db, sub_db, **token_lifetimes)

def handle_authn_response(self, context, internal_resp, extra_id_token_claims=None):
def handle_authn_response(self, context, internal_resp, extra_id_token_claims=None, **kwargs):
"""
See super class method satosa.frontends.base.FrontendModule#handle_authn_response
:type context: satosa.context.Context
Expand Down Expand Up @@ -232,7 +232,7 @@ def _get_authn_request_from_state(self, state):
"""
return AuthorizationRequest().deserialize(state[self.name]["oidc_request"])

def client_registration(self, context):
def client_registration(self, context, **kwargs):
"""
Handle the OIDC dynamic client registration.
:type context: satosa.context.Context
Expand All @@ -247,7 +247,7 @@ def client_registration(self, context):
except InvalidClientRegistrationRequest as e:
return BadRequest(e.to_json(), content="application/json")

def provider_config(self, context):
def provider_config(self, context, **kwargs):
"""
Construct the provider configuration information (served at /.well-known/openid-configuration).
:type context: satosa.context.Context
Expand All @@ -270,7 +270,7 @@ def _get_approved_attributes(self, provider_supported_claims, authn_req):
requested_claims.extend(authn_req["claims"][k].keys())
return set(provider_supported_claims).intersection(set(requested_claims))

def _handle_authn_request(self, context):
def _handle_authn_request(self, context, **kwargs):
"""
Parse and verify the authentication request into an internal request.
:type context: satosa.context.Context
Expand Down Expand Up @@ -315,7 +315,7 @@ def _handle_authn_request(self, context):
authn_req))
return internal_req

def handle_authn_request(self, context):
def handle_authn_request(self, context, **kwargs):
"""
Handle an authentication request and pass it on to the backend.
:type context: satosa.context.Context
Expand All @@ -329,7 +329,7 @@ def handle_authn_request(self, context):
return internal_req
return self.auth_req_callback_func(context, internal_req)

def jwks(self, context):
def jwks(self, context, **kwargs):
"""
Construct the JWKS document (served at /jwks).
:type context: satosa.context.Context
Expand All @@ -340,7 +340,7 @@ def jwks(self, context):
"""
return Response(json.dumps(self.provider.jwks), content="application/json")

def token_endpoint(self, context):
def token_endpoint(self, context, **kwargs):
"""
Handle token requests (served at /token).
:type context: satosa.context.Context
Expand All @@ -364,7 +364,7 @@ def token_endpoint(self, context):
error_resp = TokenErrorResponse(error=e.oauth_error, error_description=str(e))
return BadRequest(error_resp.to_json(), content="application/json")

def userinfo_endpoint(self, context):
def userinfo_endpoint(self, context, **kwargs):
headers = {"Authorization": context.request_authorization}

try:
Expand Down
4 changes: 2 additions & 2 deletions src/satosa/frontends/ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, auth_req_callback_func, internal_attributes, config, base_url

self.config = config

def handle_authn_response(self, context, internal_resp, extra_id_token_claims=None):
def handle_authn_response(self, context, internal_resp, extra_id_token_claims=None, **kwargs):
"""
See super class method satosa.frontends.base.FrontendModule#handle_authn_response
:type context: satosa.context.Context
Expand Down Expand Up @@ -47,7 +47,7 @@ def register_endpoints(self, backend_names):

return url_map

def ping_endpoint(self, context):
def ping_endpoint(self, context, **kwargs):
"""
"""
logprefix = PingFrontend.logprefix
Expand Down
Loading