/// <summary> /// Logon flow /// </summary> public ActionResult Logon() { var saml2 = new Saml2AuthenticationModule(); // parameters var assertionConsumerServiceURL = ConfigurationManager.AppSettings["AssertionConsumerServiceURL"]; var assertionIssuer = ConfigurationManager.AppSettings["AssertionIssuer"]; var identityProvider = ConfigurationManager.AppSettings["IdentityProvider"]; var artifactResolve = ConfigurationManager.AppSettings["ArtifactResolve"]; var requestBinding = Binding.POST; var responseBinding = Binding.POST; // this is optional var x509Configuration = new X509Configuration() { SignatureCertificate = new ClientCertificateProvider().GetClientCertificate(), IncludeKeyInfo = true, SignatureAlgorithm = Signature.SignatureAlgorithm.SHA256 }; // check if this is if (!saml2.IsSignInResponse(this.Request)) { // AuthnRequest factory var authnRequestFactory = new AuthnRequestFactory(); authnRequestFactory.AssertionConsumerServiceURL = assertionConsumerServiceURL; authnRequestFactory.AssertionIssuer = assertionIssuer; authnRequestFactory.Destination = identityProvider; authnRequestFactory.X509Configuration = x509Configuration; authnRequestFactory.RequestBinding = requestBinding; authnRequestFactory.ResponseBinding = responseBinding; switch (authnRequestFactory.RequestBinding) { case Constants.Binding.REDIRECT: return(Redirect(authnRequestFactory.CreateRedirectBindingContent())); case Constants.Binding.POST: return(Content(authnRequestFactory.CreatePostBindingContent())); default: throw new ArgumentException(string.Format("The {0} request binding is not supported", authnRequestFactory.RequestBinding)); } } else { // the token is created from the IdP's response Saml2SecurityToken securityToken = null; switch (responseBinding) { case Binding.ARTIFACT: var artifactConfig = new ArtifactResolveConfiguration() { ArtifactResolveUri = artifactResolve, Issuer = assertionIssuer, X509Configuration = x509Configuration }; securityToken = saml2.GetArtifactSecurityToken(this.Request, artifactConfig); break; case Binding.POST: securityToken = saml2.GetPostSecurityToken(this.Request); break; default: throw new NotSupportedException(string.Format("The {0} response binding is not yet supported", responseBinding)); } // fail if there is no token if (securityToken == null) { throw new ArgumentNullException("No security token found in the response accoding to the Response Binding configuration"); } // the token will be validated var configuration = new SecurityTokenHandlerConfiguration { CertificateValidator = X509CertificateValidator.None, IssuerNameRegistry = new DemoClientIssuerNameRegistry(), DetectReplayedTokens = false }; configuration.AudienceRestriction.AudienceMode = AudienceUriMode.Never; var tokenHandler = new Saml2SecurityTokenHandler() { Configuration = configuration }; var identity = tokenHandler.ValidateToken(securityToken); // this is the SessionIndex, store it if necessary string sessionIndex = securityToken.Assertion.ID; // the token is validated succesfully var principal = new ClaimsPrincipal(identity); if (principal.Identity.IsAuthenticated) { var formsTicket = new FormsAuthenticationTicket( 1, principal.Identity.Name, DateTime.UtcNow, DateTime.UtcNow.Add(FormsAuthentication.Timeout), false, sessionIndex); this.Response.AppendCookie(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(formsTicket))); var redirectUrl = FormsAuthentication.GetRedirectUrl(principal.Identity.Name, false); return(Redirect(redirectUrl)); } else { throw new ArgumentNullException("principal", "Unauthenticated principal returned from token validation"); } } }
/// <summary> /// Trigger SAML2 SSO AuthnRequest /// </summary> /// <returns></returns> public ActionResult Logon() { var saml2 = new Saml2AuthenticationModule(); // parameters var assertionConsumerServiceURL = ConfigurationManager.AppSettings["issuerSSO"]; var assertionIssuer = ConfigurationManager.AppSettings["issuerName"]; var identityProvider = ConfigurationManager.AppSettings["ePUAPSSO"]; var artifactResolve = ConfigurationManager.AppSettings["ePUAPArtifact"]; var getTpUserInfoUri = ConfigurationManager.AppSettings["tpUserInfo"]; var requestBinding = Binding.POST; var responseBinding = Binding.ARTIFACT; // this is optional var x509Configuration = new X509Configuration() { SignatureCertificate = new ClientCertificateProvider().GetClientCertificate(), IncludeKeyInfo = true, SignatureAlgorithm = OldMusicBox.Saml2.Signature.SignatureAlgorithm.SHA256 }; // check if this is if (!saml2.IsSignInResponse(this.Request)) { // AuthnRequest factory var authnRequestFactory = new AuthnRequestFactory(); authnRequestFactory.AssertionConsumerServiceURL = assertionConsumerServiceURL; authnRequestFactory.AssertionIssuer = assertionIssuer; authnRequestFactory.Destination = identityProvider; authnRequestFactory.X509Configuration = x509Configuration; authnRequestFactory.RequestBinding = requestBinding; authnRequestFactory.ResponseBinding = responseBinding; return(Content(authnRequestFactory.CreatePostBindingContent())); } else { // the token is created from the IdP's response var artifactConfig = new ArtifactResolveConfiguration() { ArtifactResolveUri = artifactResolve, Issuer = assertionIssuer, X509Configuration = x509Configuration }; var securityToken = saml2.GetArtifactSecurityToken(this.Request, artifactConfig); // fail if there is no token if (securityToken == null || securityToken.Assertion == null || string.IsNullOrEmpty(securityToken.Assertion.ID) ) { throw new ArgumentNullException("No valid security token found in the response accoding to the ARTIFACT Response Binding"); } // the token will be validated #warning Implement token validation // this is the SessionIndex, store it if necessary var sessionIndex = securityToken.Assertion.ID; var client = new ServiceClient(getTpUserInfoUri, x509Configuration.SignatureCertificate); FaultModel fault; var tpUserInfo = client.GetTpUserInfo(sessionIndex, out fault); if (tpUserInfo == null || !tpUserInfo.IsValid) { throw new NullReferenceException(string.Format("GetTpUserInfo returned nothing. Error message is: {0}", fault != null ? fault.FaultString : ".")); } // create the identity var identity = new ClaimsIdentity("ePUAP"); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, tpUserInfo.Podpis.Dane.DaneOsobyFizycznej.IdKontaUzytkownikaEpuap)); identity.AddClaim(new Claim(ClaimTypes.GivenName, tpUserInfo.Podpis.Dane.DaneOsobyFizycznej.Imie)); identity.AddClaim(new Claim(ClaimTypes.Surname, tpUserInfo.Podpis.Dane.DaneOsobyFizycznej.Nazwisko.Value)); identity.AddClaim(new Claim(OMBClaimTypes.PESEL, tpUserInfo.Podpis.Dane.DaneOsobyFizycznej.PESEL)); identity.AddClaim(new Claim(OMBClaimTypes.SessionIndex, sessionIndex)); if (!string.IsNullOrEmpty(tpUserInfo.Return.AccountEmailAddress)) { identity.AddClaim(new Claim(ClaimTypes.Email, tpUserInfo.Return.AccountEmailAddress)); } // the token is validated succesfully var principal = new ClaimsPrincipal(identity); if (principal.Identity.IsAuthenticated) { // use the SessionAuthenticationModule to store the auth cookie var sam = FederatedAuthentication.SessionAuthenticationModule; var token = sam.CreateSessionSecurityToken(principal, string.Empty, DateTime.Now.ToUniversalTime(), DateTime.Now.AddMinutes(20).ToUniversalTime(), false); sam.WriteSessionTokenToCookie(token); // fixed return url because the provider redirects here without the query string return(Redirect("/Home/Signed")); } else { throw new ArgumentNullException("principal", "Unauthenticated principal returned from token validation"); } } }