Hello everyone,
I have been looking into PR #495
https://github.com/IdentityPython/pysaml2/pull/495
What the user needs is an option to configure the signing algorithm
that will be used by the SP to sign an authentication request. This
comes in hand with the digest algorithm and in extension what is
entity that should be signed.
What the proposed one line change does, is allows this value to exist
in pysaml2 Config object. By itself, it does not affect anything in
the code - it does not set the signing algorithm. It is only a
placeholder for a value. Something else is supposed to look at that
value, at the right time, and pass it as an argument to the
appropriate function/method.
This doesn't seem right. If it is in the configuration, then it should
actually do something - it should affect the way the library behaves.
Looking into this I stumbled upon some commits, made about a year ago,
that implement some of this functionality for the IdP part:
* 2aedfa0 - make both sign response and assertion configurable
adds sign_assertion and sign_response options
* bd4303a - Signing signature and digest algorithm configuration
adds sign_alg and digest_alg options
These are implemented in the SATOSA repository (see
satosa/frontends/saml2.py the _handle_authn_response method). However,
their configuration lies between the lines of the pysaml2
configuration (under service/idp/policy). This is wrong - each project
should be responsible for its own configuration. The code that decides
what should be signed and how, should live in pysaml2. If it is
handled by SATOSA then it should be part of the SATOSA configuration
and an override of the pysaml2 configuration.
Moreover, it seems that this functionality was partially already there
in pysaml2 in the first place. See the Policy class in
saml2/assertion.py and its get_sign method. An option named 'sign' can
be defined under the service/idp/policy part of the configuration,
that defines an array of values that represent what should be signed,
for example:
service:
idp:
policy:
sign:
- response
- assertion
So now we have both the above 'sign' option, plus 'sign_assertion' and
'sign_response', which should do the same thing.
What I would like to do is move the code introduced by the commits
above into pysaml2: this will allow a consistent behaviour whether
pysaml2 is used by SATOSA or some other project. Then the same options
can be used by the backend too, which would satisfy the user request.
Once that is done we can look into making the configuration work in
one way.
This is bigger than it looks. What happens now is that we define for
example, that we want to use SHA512 as a sign_alg. This will be used
when a authentication response is formed, but it is ignored when for
example a logout request is to be created. This happens because the
configuration of what signing algorithm will be used is only
implemented for the authentication response.
There are two ways to fix this:
- we either assume that a configuration option like 'sign_alg' is
global, and as such, it affects the signing algorithm of anything that
is to be signed
- or we assume that it relates to the authentication req/response only
(and in that case it shold probably be called authn_sign_alg or alike)
and require new options for other kinds of signatures
(logout_sign_alg, metadata_sign_alg, etc).
The first solution requires that we find all places in the code use
signatures and make sure they respect the configuration. I have
already noted (a lot of) entry points to pysaml2 that should be
looking into the configuration to derive the signing and digest
algorithm values.
The second option is "easier" to work with, as it allows for an
incremental implementation of this request. The second approach is
also more flexible for the end user, but at the same time more complex
as it requires more configuration values to be set.
Ofcourse we can have both, use an option like sign_alg to defined the
signing algorithm, and use "suboptions" like authn_sign_alg to
override the sign_alg setting where needed.
I hope this makes sense (even though it mixes at least four
configuration options together). If you have any comments, I'd like to
hear.
Cheers,
--
Ivan c00kiemon5ter Kanakarakis >:3
Hi,
I know it has been talked about as "doable", but has anybody already
deployed SATOSA with a response microservice that implements a "step-up"
flow to leverage a second factor (like Duo) when the authenticating IdP
does not assert that MFA was used?
If so, are you considering sharing it and/or contributing it to the code
base?
If not, but you are considering such an implementation/deployment, can
you indicate if you are interested in collaborating on the development
and testing?
Thanks,
Scott K
Hi to everybody,
I developed a microservice that can map specific SaToSa backends to
specific target entity id. A configuration example can be this:
````
module: satosa.micro_services.custom_routing.DecideBackendByTarget
name: TargetRouter
config:
target_mapping:
"http://idpspid.testunical.it:8088": "spidSaml2"
"http://strangeIDP.testunical.it:8081/saml2/metadata": "strangeSaml2"
````
I needed a backend routing based on the target entity ID because I have
some SAML2 IDP that only accepts highly customized authn request and
metadata. An example would be SPID italian federation, through which my
organization will federate soon with SaToSa. Another example could be the
need to use different configurations, like enc and digest algorithms,
depending by target IDP.
I was looking into DecideBackendByRequester microservice but soon I
realized that it was made for different goals, in it the subjects are the
requester entity ID and not the target entity ID.
As you can see in https://github.com/IdentityPython/SATOSA/pull/220
I made a single branch to pull only this feature.
I'm also curious about SaToSa milestone, which are the features in
development status, which will compose the next release and another
question about the possibility to have a dev branch to do PR on it.
I don't know if this microservice could sound useless to you, I searched a
lot before programming it and I hope to have done a middleware that could
be usefull for the SaToSa community.
Hope to hear your comments soon
Hi,
Right now the saml2.py in src/satosa/backends/ has
def disco_query(self):
"""
Makes a request to the discovery server
:type context: satosa.context.Context
:type internal_req: satosa.internal.InternalData
:rtype: satosa.response.SeeOther
:param context: The current context
:param internal_req: The request
:return: Response
"""
return_url = self.sp.config.getattr("endpoints", "sp")["discovery_response"][0][0]
loc = self.sp.create_discovery_service_request(self.discosrv, self.sp.config.entityid, **{"return": return_url})
return SeeOther(loc)
Essentially this restricts the flow to one and only one IdP discovery
service that is configured statically.
I propose that this method be enhanced so that it can inspect the context
and internal data and if it finds a URL for the discovery service to use
it overrides what is in the configuration.
Then one can configure a request microservice that uses some logic to set
the URL for the discovery service, such as which SP the authentication
request came from.
Since the comment for the method already includes a mention of the context
and internal data, I suspect this functionality was designed but never
implemented.
Any objections to me implementing it?
Any other comments or input?
Thanks,
Scott K