Local SSO integration with IdP 5.1.1
Christopher Bongaarts
cab at umn.edu
Thu Apr 18 23:49:28 UTC 2024
On 4/17/2024 8:36 AM, Cantor, Scott wrote:
>> How about an entry in the transition map from authn/External to catch
>> NoCredentials (which for me is the "usual" case of no special SSO
>> cookies present) that runs a next flow strategy function that
>> clears/overwrites whatever is getting passed to Password
>> (AuthenticationError/WarningContext? Spring event?)?
> The event should not be messed with. I don't think that the others would be there, but if they are then yes, they could be cleared or removed without hurting anything.
Closing the loop - this seems to be working for me.
mfa-authn-config.xml excerpt:
<entry key=""> <bean parent="shibboleth.authn.MFA.Transition"
p:nextFlow="authn/External" /> </entry> <entry key="authn/External">
<bean parent="shibboleth.authn.MFA.Transition"> <property
name="nextFlowStrategyMap"> <map> <!-- if external auth succeeded, stop
here, else goto password --> <entry key="proceed" value="proceed" />
<entry key="*" value-ref="clearExternalError" /> </map> </property>
</bean> </entry> [...] <bean id="clearExternalError"
parent="shibboleth.ContextFunctions.Scripted"
factory-method="inlineScript"> <constructor-arg> <value> <![CDATA[
authCtx =
input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
errCtx =
authCtx.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationErrorContext");
if (errCtx != null) { errs = errCtx.getClassifiedErrors(); if (errs !=
null && errs.contains("NoCredentials")) {
authCtx.removeSubcontext(errCtx); } } "authn/Password"; // regardless,
go to password flow next ]]> </value> </constructor-arg> </bean>
------------------------------------------------------------------------
external.jsp:
<%@ page pageEncoding="UTF-8" %> <%@ page
import="net.shibboleth.idp.authn.ExternalAuthentication" %> <%@ page
import="net.shibboleth.idp.authn.ExternalAuthenticationException" %> <%@
page import="org.opensaml.profile.context.ProfileRequestContext" %> <%@
page import="java.time.Instant" %> <%@ page
import="java.security.Principal" %> <%@ page
import="javax.security.auth.Subject" %> <%@ page
import="net.shibboleth.idp.authn.principal.UsernamePrincipal" %> <%@
page
import="net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal"
%> <%@ page import="org.opensaml.saml.saml2.core.AuthnContext" %> <%@
page import="net.shibboleth.idp.session.context.SessionContext" %> <%@
page import="net.shibboleth.idp.session.IdPSession" %> <%@ page
import="java.util.Collections" %> <%@ page import="java.util.HashSet" %>
<% try { final String key =
ExternalAuthentication.startExternalAuthentication(request); /* check
for an existing IdPSession inside a possibly null SessionContext */
final ProfileRequestContext prc =
ExternalAuthentication.getProfileRequestContext(key, request); final
SessionContext sc = prc.getSubcontext(SessionContext.class); IdPSession
idpsession = null; if (sc != null) { idpsession = sc.getIdPSession(); }
/* only check cookie if no existing session - this SSO only works for
the first SP you hit */ if (idpsession == null) { try { final CAHUser
cahUser = processSSOCookies(request); if (cahUser != null) { /* got a
yummy cookie, lets make a subject out of it */ HashSet<Principal>
principals = new HashSet<Principal>(); principals.add(new
UsernamePrincipal(cahUser.getUid())); principals.add(new
AuthnContextClassRefPrincipal(AuthnContext.UNSPECIFIED_AUTHN_CTX));
final Subject subj = new Subject(false, principals,
Collections.emptySet(), Collections.emptySet());
request.setAttribute(ExternalAuthentication.SUBJECT_KEY, subj);
request.setAttribute(ExternalAuthentication.AUTHENTICATION_INSTANT_KEY,
Instant.ofEpochSecond(cahUser.getTimestamp()));
request.setAttribute(ExternalAuthentication.PREVIOUSRESULT_KEY, true); }
else { /* got yucky or no cookie */ /* do nothing; idp will throw
NO_CREDENTIALS event which we want */ } } catch (final CAHException e) {
request.setAttribute(ExternalAuthentication.AUTHENTICATION_EXCEPTION_KEY,
new ExternalAuthenticationException("CAH handling error", e)); } } else
{ /* do nothing; idp will throw NO_CREDENTIALS event which we want */ }
ExternalAuthentication.finishExternalAuthentication(key, request,
response); } catch (final ExternalAuthenticationException e) { throw new
ServletException("Error processing external authentication request", e);
} %>
There are no methods to remove ClassifiedErrors from the
AuthenticationErrorContext, so I just remove the whole context if I find
the NoCredentials present.
Thanks Scott for the direction as always, and thanks Steve taking a stab
at it too!
--
%% Christopher A. Bongaarts %%cab at umn.edu %%
%% OIT - Identity Management %%http://umn.edu/~cab %%
%% University of Minnesota %% +1 (612) 625-1809 %%
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/dev/attachments/20240418/e6aee565/attachment.htm>
More information about the dev
mailing list