mfa through adfs university of washington customized its adfs to enable mfa eric kool-brown...
TRANSCRIPT
MFA Through ADFSUniversity of Washington Customized its ADFS to Enable MFA
Eric Kool-Brown ([email protected])Software Engineer, UW IT Identity and Access Management
ADFS Auth Flow
Home Realm Discovery Customization• UW WebLogin (Shibboleth SAMLP) added to ADFS as second claims
trust provider (CTP)• ADFS 2.0 implements Home Realm Discovery through an ASP.Net web
page that by default gives the user a choice of which CTP to use• UW IT modified this ASP.Net page to automatically redirect to WebLogin
for most Relying Parties (RPs)• Several RPs requested two-factor authentication• WebLogin supports MFA via Entrust tokens• HRD .Net code does a URL rewrite to add the TimeSyncToken parameter
for RPs that require 2-factor
Observations
• No step-up authentication – it is all or nothing per RP• Currently code modifications and XML config file need to be on each
ADFS server• Unknown if these modifications are possible with ADFS 3.0• A web app written to be a SAMLP service provider can request step-up
auth at any point (no ADFS in this scenario)• UW WebLogin must release all RP-requested attributes on every auth
request; claims rules filter them per-RP• Could share the UW code, unsure what the licensing would be due to
the original code being owned by Microsoft
switch (entry.HrdAction) { case RpHrdActions.GotoShib: // Default action if (CheckWauthForShib(false)) { SelectHomeRealm(UwShibUrn); } break; case RpHrdActions.GotoShib2Factor: if (CheckWauthForShib(true)) { SelectHomeRealm(UwShibUrn); } return; case RpHrdActions.GotoAd: // An empty string means go to AD for auth. SelectHomeRealm(""); return; case RpHrdActions.ShowHrdPage: PassiveIdentityProvidersDropDownList.DataSource = ClaimsProviders; PassiveIdentityProvidersDropDownList.DataBind(); return; }
// If Shib will be used for authentication, make sure a valid wauth parameter is included.// For ordinary password login to Shib the wauth can either be null (not included in the params)// or be Saml2Constants.AuthenticationContextClasses.PasswordProtectedTransport. If 2-factor is// required then wauth must be Saml2Constants.AuthenticationContextClasses.TimeSyncToken.private bool CheckWauthForShib(bool require2factor){ Uri url = HttpContext.Current.Request.Url; NameValueCollection urlParamNvc = HttpUtility.ParseQueryString(url.Query); string requiredWauth = require2factor ? Saml2Constants.AuthenticationContextClasses.TimeSyncToken.ToString() : Saml2Constants.AuthenticationContextClasses.PasswordProtectedTransport.ToString(); if (urlParamNvc[Wauth] != requiredWauth && (require2factor || !string.IsNullOrEmpty(urlParamNvc[Wauth]))) { LogInfo("Did not find wauth param with value {0}", requiredWauth); urlParamNvc.Set(Wauth, requiredWauth); string redirect = url.AbsolutePath + "?" + urlParamNvc; LogInfo("Redirecting to {0}", redirect); Response.Redirect(redirect, true); return false; } return true;}