/// <summary> /// Attempts to validate a ticket for the provided service. /// </summary> /// <param name="ticket">the ticket to validate</param> /// <returns> /// The ICasPrincipal backed by the CAS Assertion included in the response /// from the CAS server for a successful ticket validation. /// </returns> /// <exception cref="TicketValidationException"> /// Thrown if ticket validation fails. /// </exception> public ICasPrincipal Validate(string ticket) { string validationUrl = UrlUtil.ConstructValidateUrl(ticket, CasAuthentication.Gateway, CasAuthentication.Renew, CustomParameters); protoLogger.Debug("Constructed validation URL " + validationUrl); string serverResponse; try { serverResponse = RetrieveResponseFromServer(validationUrl, ticket); } catch (Exception e) { protoLogger.Info("Ticket validation failed: " + e); throw new TicketValidationException("CAS server ticket validation threw an Exception", e); } if (serverResponse == null) { protoLogger.Warn("CAS server returned no response"); throw new TicketValidationException("The CAS server returned no response."); } protoLogger.Debug("Ticket validation response:{0}{1}", Environment.NewLine, serverResponse); ICasPrincipal principal = ParseResponseFromServer(serverResponse, ticket); return(principal); }
protected void Page_Load(object sender, EventArgs e) { System.Text.StringBuilder retVal = new System.Text.StringBuilder(); ICasPrincipal p = HttpContext.Current.User as ICasPrincipal; if (p != null) { foreach (System.Collections.Generic.KeyValuePair <string, IList <string> > grouping in p.Assertion.Attributes) { retVal.Append(@"<br/>" + grouping.Key + ": "); foreach (string attrValue in p.Assertion.Attributes[grouping.Key]) { retVal.Append(attrValue); } } } Response.Write(retVal.ToString()); int cwid = CasAuthentication.CurrentPrincipal == null ? 100 : Int32.Parse(CasAuthentication.CurrentPrincipal.Assertion.Attributes["employeeID"][0]); if (HearMyNameHelper.isUserAnAdmin(cwid)) { Response.Redirect("~/Admin/Default.aspx"); } else { Response.Redirect("~/Profile.aspx"); } }
public CasAuthenticationMiddlewareTest() { // Arrange var principalName = Guid.NewGuid().ToString(); principal = new CasPrincipal(new Assertion(principalName), "CAS"); ticketValidator = Mock.Of <IServiceTicketValidator>(); options = new CasAuthenticationOptions { ServiceTicketValidator = ticketValidator, CasServerUrlBase = "http://example.com/cas" }; server = new TestServer(new WebHostBuilder() .ConfigureServices(services => { services.AddAuthentication(options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme); services.Configure <CookieAuthenticationOptions>(options => { options.AutomaticAuthenticate = true; options.AutomaticChallenge = true; options.LoginPath = new PathString("/login"); options.LogoutPath = new PathString("/logout"); }); }) .Configure(app => { app.UseCookieAuthentication(); app.UseCasAuthentication(options); app.Use(async(context, next) => { var request = context.Request; if (request.Path.StartsWithSegments(new PathString("/login"))) { await context.Authentication.ChallengeAsync(options.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" }); } else if (request.Path.StartsWithSegments(new PathString("/logout"))) { await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); } await next.Invoke(); }); app.Run(async context => { var user = context.User; // Deny anonymous request beyond this point. if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated)) { await context.Authentication.ChallengeAsync(options.AuthenticationScheme); return; } // Display authenticated user id await context.Response.WriteAsync((user.Identity as ClaimsIdentity)?.FindFirst(ClaimTypes.NameIdentifier)?.Value); }); })); client = server.CreateClient(); }
protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync() { var query = Request.Query; var state = query["state"]; var properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(AuthenticateResult.Fail("The state was missing or invalid.")); } // CSRF if (!ValidateCorrelationId(properties)) { return(AuthenticateResult.Fail("Correlation failed.")); } var ticket = query["ticket"]; if (string.IsNullOrEmpty(ticket)) { return(AuthenticateResult.Fail("Missing CAS ticket.")); } var service = BuildRedirectUri($"{Options.CallbackPath}?state={Uri.EscapeDataString(state)}"); ICasPrincipal principal = null; try { principal = await Options.ServiceTicketValidator.ValidateAsync(ticket, service, Context.RequestAborted); } catch (Exception e) { Logger.LogWarning(e.Message, e); return(AuthenticateResult.Fail("There was a problem validating ticket.")); } if (principal == null) { return(AuthenticateResult.Fail("Missing Validate Principal.")); } if (Options.UseTicketStore) { properties.SetServiceTicket(ticket); } var ticketContext = new CasCreatingTicketContext(Context, Options) { Principal = principal as ClaimsPrincipal ?? new ClaimsPrincipal(principal), Properties = properties }; await Options.Events.CreatingTicket(ticketContext); return(AuthenticateResult.Success(new AuthenticationTicket( ticketContext.Principal, ticketContext.Properties, Options.AuthenticationScheme))); }
public CasAuthenticationMiddlewareTest() { // Arrange var principalName = Guid.NewGuid().ToString(); principal = new CasPrincipal(new Assertion(principalName), "CAS"); ticketValidator = Mock.Of <IServiceTicketValidator>(); options = new CasAuthenticationOptions { ServiceTicketValidator = ticketValidator, CasServerUrlBase = "http://example.com/cas" }; server = TestServer.Create(app => { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { LoginPath = new PathString("/login"), LogoutPath = new PathString("/logout") }); app.UseCasAuthentication(options); app.Use((context, next) => { var request = context.Request; if (request.Path.StartsWithSegments(new PathString("/login"))) { context.Authentication.Challenge(new AuthenticationProperties() { RedirectUri = "/" }, options.AuthenticationType); } else if (request.Path.StartsWithSegments(new PathString("/logout"))) { context.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); } return(next.Invoke()); }); app.Run(async context => { var user = context.Authentication.User; // Deny anonymous request beyond this point. if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated)) { context.Authentication.Challenge(options.AuthenticationType); return; } // Display authenticated principal name await context.Response.WriteAsync(user.GetPrincipalName()); }); }); client = server.HttpClient; }
private IList <string> GetCurrentUserRoles() { ICasPrincipal principal = CasAuthentication.CurrentPrincipal; if (principal == null) { return(EMPTY_LIST); } IList <string> roles = principal.Assertion.Attributes[roleAttribute]; if (roles == null) { roles = EMPTY_LIST; } return(roles); }
protected void Page_Load(object sender, EventArgs e) { isNSO = string.IsNullOrEmpty(Request.QueryString["NSO"]) ? false : true; hdnIsNSO.Value = isNSO.ToString(); ICasPrincipal p = HttpContext.Current.User as ICasPrincipal; CWID = p == null ? "100538403" : p.Assertion.Attributes["employeeID"][0]; Name = getStudentNameFromCWID(CWID); systemName = p == null ? "Test Subject (REMOVE ME) SystemName" : p.Assertion.Attributes["displayName"][0]; email = p == null ? "*****@*****.**" : p.Assertion.Attributes["mail"][0]; NTID = p == null ? "test" : p.Assertion.Attributes["sAMAccountName"][0]; if (Name.Count(x => x == ',') == 1) { Name = Name.Split(',')[1] + " " + Name.Split(',')[0]; Name = replaceEverythingInParenthesis(Name); } if (systemName.Count(x => x == ',') == 1) { systemName = systemName.Split(',')[1] + " " + systemName.Split(',')[0]; systemName = replaceEverythingInParenthesis(systemName); } if (Helpers.HearMyNameHelper.isUserAnAdmin(Int32.Parse(CWID))) { liReview.Visible = true; } Session.Add("CurrentUserID", CWID); hdnemail.Value = email; hdnNTID.Value = NTID; hdnStudentSystemName.Value = replaceEverythingInParenthesis(systemName); LoadData(); }
private string getStudentNameFromCWID(string cwid) { ICasPrincipal p = HttpContext.Current.User as ICasPrincipal; string fullName = string.Empty; StudentInformation info = new StudentInformation(); using (var db = new HearMyNameEntities()) { info = db.StudentInformations.FirstOrDefault(A => A.EMPLID.Equals(cwid.ToString().Trim())); } if (info == null) { fullName = (p == null ? "Daniil Gedgafov" : p.Assertion.Attributes["displayName"][0]); } else { fullName = info.FIRST_NAME + ' ' + info.MIDDLE_NAME + ' ' + info.LAST_NAME; } return(fullName); }
/// <summary> /// Initializes the CAS IAssertion for this instance from the first valid /// Assertion node in the CAS server response. /// </summary> /// <exception cref="TicketValidationException"> /// Thrown when data problems are encountered parsing /// the CAS server response that contains the Assertion, such as /// no valid Assertion found or no Authentication statment found in the /// the valid Assertion. /// </exception> private void ProcessValidAssertion() { protoLogger.Debug("Unmarshalling SAML response"); XmlDocument document = new XmlDocument(); document.Load(new StringReader(_CasResponse)); XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable); nsmgr.AddNamespace("assertion", SAML11_ASSERTION_NAMESPACE); if (document.DocumentElement != null) { XmlNodeList assertions = document.DocumentElement.SelectNodes("descendant::assertion:Assertion", nsmgr); if (assertions == null || assertions.Count < 1) { protoLogger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No assertions found."); } XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); xmlReaderSettings.ConformanceLevel = ConformanceLevel.Auto; xmlReaderSettings.IgnoreWhitespace = true; xmlReaderSettings.IgnoreComments = true; xmlReaderSettings.CloseInput = true; foreach (XmlNode assertionNode in assertions) { XmlNode conditionsNode = assertionNode.SelectSingleNode("descendant::assertion:Conditions", nsmgr); if (conditionsNode == null) { continue; } DateTime notBefore; DateTime notOnOrAfter; try { notBefore = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotBefore"); notOnOrAfter = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotOnOrAfter"); if (!SamlUtils.IsValidAssertion(notBefore, notOnOrAfter, _ToleranceTicks)) { continue; } } catch (Exception) { continue; } XmlNode authenticationStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AuthenticationStatement", nsmgr); if (authenticationStmtNode == null) { protoLogger.Debug("No AuthenticationStatement found in SAML response."); throw new TicketValidationException("No AuthenticationStatement found in the CAS response."); } string authMethod = SamlUtils.GetAttributeValue(authenticationStmtNode.Attributes, "AuthenticationMethod"); XmlNode nameIdentifierNode = assertionNode.SelectSingleNode("child::assertion:AuthenticationStatement/child::assertion:Subject/child::assertion:NameIdentifier", nsmgr); if (nameIdentifierNode == null) { protoLogger.Debug("No NameIdentifier found in SAML response."); throw new TicketValidationException("No NameIdentifier found in AuthenticationStatement of the CAS response."); } string subject = nameIdentifierNode.FirstChild.Value; XmlNode attributeStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AttributeStatement", nsmgr); IDictionary<string, IList<string>> personAttributes = SamlUtils.GetAttributesFor(attributeStmtNode, nsmgr, subject); IDictionary<string, IList<string>> authenticationAttributes = new Dictionary<string, IList<string>>(); IList<string> authValues = new List<string>(); authValues.Add(authMethod); authenticationAttributes.Add("samlAuthenticationStatement::authMethod", authValues); IAssertion casAssertion = new Assertion(subject, notBefore, notOnOrAfter, personAttributes); CasPrincipal = new CasPrincipal(casAssertion, null, null); return; } } protoLogger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); }
static public User GetUser(IPrincipal user, HttpSessionStateBase session) { ICasPrincipal sessionPrincipal = user as ICasPrincipal; IAssertion sessionAssertion = sessionPrincipal.Assertion; User userObject = new User(); userObject.NetID = sessionPrincipal.Identity.Name; try { List <string> firstname = sessionAssertion.Attributes["GivenName"].ToList(); string fname = string.Join("", firstname.ToArray()); userObject.FirstName = fname; } catch { userObject.FirstName = ""; } try { List <string> lastname = sessionAssertion.Attributes["Surname"].ToList(); string lname = string.Join("", lastname.ToArray()); userObject.LastName = lname; } catch { userObject.LastName = ""; } try { List <string> UID = sessionAssertion.Attributes["USFeduUnumber"].ToList(); string USFID = string.Join("", UID.ToArray()); userObject.UID = USFID; } catch { userObject.UID = ""; } try { List <string> email = sessionAssertion.Attributes["mail"].ToList(); string Email = string.Join("", email.ToArray()); userObject.Email = Email; } catch { userObject.Email = ""; } session["user"] = userObject; return(userObject); }
public CasAuthenticationTest(CasFixture fixture) { _fixture = fixture; // Arrange var principalName = Guid.NewGuid().ToString(); _principal = new CasPrincipal(new Assertion(principalName), CasDefaults.AuthenticationType); _ticketValidator = Mock.Of <IServiceTicketValidator>(); _server = new TestServer(new WebHostBuilder() .ConfigureServices(services => { services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/login"; options.LogoutPath = "/logout"; }) .AddCAS(options => { options.CallbackPath = "/signin-cas"; options.ServiceTicketValidator = _ticketValidator; options.CasServerUrlBase = fixture.Options.CasServerUrlBase; options.Events = new CasEvents { OnCreatingTicket = context => { var assertion = context.Assertion; if (assertion == null) { return(Task.CompletedTask); } if (!(context.Principal.Identity is ClaimsIdentity identity)) { return(Task.CompletedTask); } identity.AddClaim(new Claim(identity.NameClaimType, assertion.PrincipalName)); return(Task.CompletedTask); } }; }); }) .Configure(app => { app.UseAuthentication(); app.Use(async(context, next) => { var request = context.Request; if (request.Path.StartsWithSegments(new PathString("/login"))) { await context.ChallengeAsync(CasDefaults.AuthenticationType, new AuthenticationProperties { RedirectUri = "/" }).ConfigureAwait(false); return; } if (request.Path.StartsWithSegments(new PathString("/logout"))) { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme).ConfigureAwait(false); } await next.Invoke().ConfigureAwait(false); }); app.Run(async context => { var user = context.User; // Deny anonymous request beyond this point. if (user?.Identities.Any(identity => identity.IsAuthenticated) != true) { await context.ChallengeAsync(CasDefaults.AuthenticationType).ConfigureAwait(false); return; } // Display authenticated user id var claimsIdentity = user.Identity as ClaimsIdentity; await context.Response.WriteAsync(claimsIdentity?.FindFirst(claimsIdentity.NameClaimType)?.Value).ConfigureAwait(false); }); })); _client = _server.CreateClient(); }
/// <summary> /// Attempts to authenticate requests subsequent to the initial authentication /// request (handled by ProcessTicketValidation). This method looks for a /// FormsAuthenticationCookie containing a FormsAuthenticationTicket and attempts /// to confirms its validitiy. It either contains the CAS service ticket or a /// reference to a CasAuthenticationTicket stored in the ServiceTicketManager /// (if configured). If it succeeds, the context.User and Thread.CurrentPrincipal /// are set with a ICasPrincipal and the current request is considered /// authenticated. Otherwise, the current request is effectively anonymous. /// </summary> internal static void ProcessRequestAuthentication() { HttpContext context = HttpContext.Current; // Look for a valid FormsAuthenticationTicket encrypted in a cookie. CasAuthenticationTicket casTicket = null; FormsAuthenticationTicket formsAuthenticationTicket = GetFormsAuthenticationTicket(); if (formsAuthenticationTicket != null) { ICasPrincipal principal; if (ServiceTicketManager != null) { string serviceTicket = formsAuthenticationTicket.UserData; casTicket = ServiceTicketManager.GetTicket(serviceTicket); if (casTicket != null) { IAssertion assertion = casTicket.Assertion; if (!ServiceTicketManager.VerifyClientTicket(casTicket)) { securityLogger.Warn("CasAuthenticationTicket failed verification: " + casTicket); // Deletes the invalid FormsAuthentication cookie from the client. ClearAuthCookie(); ServiceTicketManager.RevokeTicket(serviceTicket); // Don't give this request a User/Principal. Remove it if it was created // by the underlying FormsAuthenticationModule or another module. principal = null; } else { if (ProxyTicketManager != null && !string.IsNullOrEmpty(casTicket.ProxyGrantingTicketIou) && string.IsNullOrEmpty(casTicket.ProxyGrantingTicket)) { string proxyGrantingTicket = ProxyTicketManager.GetProxyGrantingTicket(casTicket.ProxyGrantingTicketIou); if (!string.IsNullOrEmpty(proxyGrantingTicket)) { casTicket.ProxyGrantingTicket = proxyGrantingTicket; } } principal = new CasPrincipal(assertion); } } else { // This didn't resolve to a ticket in the TicketStore. Revoke it. ClearAuthCookie(); securityLogger.Debug("Revoking ticket " + serviceTicket); ServiceTicketManager.RevokeTicket(serviceTicket); // Don't give this request a User/Principal. Remove it if it was created // by the underlying FormsAuthenticationModule or another module. principal = null; } } else { principal = new CasPrincipal(new Assertion(formsAuthenticationTicket.Name)); } context.User = principal; Thread.CurrentPrincipal = principal; currentPrincipal = principal; if (principal == null) { // Remove the cookie from the client ClearAuthCookie(); } else { // Extend the expiration of the cookie if FormsAuthentication is configured to do so. if (FormsAuthentication.SlidingExpiration) { FormsAuthenticationTicket newTicket = FormsAuthentication.RenewTicketIfOld(formsAuthenticationTicket); if (newTicket != null && newTicket != formsAuthenticationTicket) { SetAuthCookie(newTicket); if (ServiceTicketManager != null) { ServiceTicketManager.UpdateTicketExpiration(casTicket, newTicket.Expiration); } } } } } }
/// <summary> /// Initializes the CAS IAssertion for this instance from the first valid /// Assertion node in the CAS server response. /// </summary> /// <exception cref="TicketValidationException"> /// Thrown when data problems are encountered parsing /// the CAS server response that contains the Assertion, such as /// no valid Assertion found or no Authentication statment found in the /// the valid Assertion. /// </exception> private void ProcessValidAssertion() { protoLogger.Debug("Unmarshalling SAML response"); XmlDocument document = new XmlDocument(); document.Load(new StringReader(_CasResponse)); XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable); nsmgr.AddNamespace("assertion", SAML11_ASSERTION_NAMESPACE); if (document.DocumentElement != null) { XmlNodeList assertions = document.DocumentElement.SelectNodes("descendant::assertion:Assertion", nsmgr); if (assertions == null || assertions.Count < 1) { protoLogger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No assertions found."); } XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); xmlReaderSettings.ConformanceLevel = ConformanceLevel.Auto; xmlReaderSettings.IgnoreWhitespace = true; xmlReaderSettings.IgnoreComments = true; xmlReaderSettings.CloseInput = true; foreach (XmlNode assertionNode in assertions) { XmlNode conditionsNode = assertionNode.SelectSingleNode("descendant::assertion:Conditions", nsmgr); if (conditionsNode == null) { continue; } DateTime notBefore; DateTime notOnOrAfter; try { notBefore = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotBefore"); notOnOrAfter = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotOnOrAfter"); if (!SamlUtils.IsValidAssertion(notBefore, notOnOrAfter, _ToleranceTicks)) { continue; } } catch (Exception) { continue; } XmlNode authenticationStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AuthenticationStatement", nsmgr); if (authenticationStmtNode == null) { protoLogger.Debug("No AuthenticationStatement found in SAML response."); throw new TicketValidationException("No AuthenticationStatement found in the CAS response."); } string authMethod = SamlUtils.GetAttributeValue(authenticationStmtNode.Attributes, "AuthenticationMethod"); XmlNode nameIdentifierNode = assertionNode.SelectSingleNode("child::assertion:AuthenticationStatement/child::assertion:Subject/child::assertion:NameIdentifier", nsmgr); if (nameIdentifierNode == null) { protoLogger.Debug("No NameIdentifier found in SAML response."); throw new TicketValidationException("No NameIdentifier found in AuthenticationStatement of the CAS response."); } string subject = nameIdentifierNode.FirstChild.Value; XmlNode attributeStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AttributeStatement", nsmgr); IDictionary <string, IList <string> > personAttributes = SamlUtils.GetAttributesFor(attributeStmtNode, nsmgr, subject); IDictionary <string, IList <string> > authenticationAttributes = new Dictionary <string, IList <string> >(); IList <string> authValues = new List <string>(); authValues.Add(authMethod); authenticationAttributes.Add("samlAuthenticationStatement::authMethod", authValues); IAssertion casAssertion = new Assertion(subject, notBefore, notOnOrAfter, personAttributes); CasPrincipal = new CasPrincipal(casAssertion, null, null); return; } } protoLogger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); }
/// <summary> /// Initializes the CAS IAssertion for this instance from the first valid /// Assertion node in the CAS server response. /// </summary> /// <exception cref="TicketValidationException"> /// Thrown when data problems are encountered parsing /// the CAS server response that contains the Assertion, such as /// no valid Assertion found or no Authentication statment found in the /// the valid Assertion. /// </exception> private void ProcessValidAssertion(string response) { _logger.Debug("Unmarshalling SAML response"); var document = new XmlDocument(); document.LoadXml(response); var nsmgr = new XmlNamespaceManager(document.NameTable); nsmgr.AddNamespace("assertion", SAML11_ASSERTION_NAMESPACE); if (document.DocumentElement == null) { _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); } var assertions = document.DocumentElement.SelectNodes("descendant::assertion:Assertion", nsmgr); if (assertions == null || assertions.Count <= 0) { _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No assertions found."); } var currentTicks = _clock.UtcNow.Ticks; foreach (XmlNode assertionNode in assertions) { XmlNode conditionsNode = assertionNode.SelectSingleNode("descendant::assertion:Conditions", nsmgr); if (conditionsNode == null) { continue; } DateTime notBefore; DateTime notOnOrAfter; try { notBefore = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotBefore"); notOnOrAfter = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotOnOrAfter"); if (!SamlUtils.IsValidAssertion(_logger, notBefore, notOnOrAfter, currentTicks, _toleranceTicks)) { continue; } } catch (Exception) { continue; } XmlNode authenticationStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AuthenticationStatement", nsmgr); if (authenticationStmtNode == null) { _logger.Debug("No AuthenticationStatement found in SAML response."); throw new TicketValidationException("No AuthenticationStatement found in the CAS response."); } XmlNode nameIdentifierNode = assertionNode .SelectSingleNode("child::assertion:AuthenticationStatement/child::assertion:Subject/child::assertion:NameIdentifier", nsmgr); if (nameIdentifierNode == null) { _logger.Debug("No NameIdentifier found in SAML response."); throw new TicketValidationException("No NameIdentifier found in AuthenticationStatement of the CAS response."); } string subject = nameIdentifierNode.FirstChild.Value; XmlNode attributeStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AttributeStatement", nsmgr); if (attributeStmtNode != null) { IDictionary <string, List <string> > personAttributes = SamlUtils.GetAttributesFor(_logger, attributeStmtNode, nsmgr, subject); CasPrincipal = new CasPrincipal(new Assertion(subject, notBefore, notOnOrAfter, personAttributes), null, null); } else { CasPrincipal = new CasPrincipal(new Assertion(subject, notBefore, notOnOrAfter), null, null); } return; } _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); }
public CasAuthenticationMiddlewareTest(CasFixture fixture) { _fixture = fixture; // Arrange var principalName = Guid.NewGuid().ToString(); _principal = new CasPrincipal(new Assertion(principalName), CasDefaults.AuthenticationType); _ticketValidator = Mock.Of <IServiceTicketValidator>(); _server = TestServer.Create(app => { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { LoginPath = new PathString("/login"), LogoutPath = new PathString("/logout") }); app.UseCasAuthentication(new CasAuthenticationOptions { CallbackPath = new PathString("/signin-cas"), ServiceTicketValidator = _ticketValidator, CasServerUrlBase = fixture.Options.CasServerUrlBase, Provider = new CasAuthenticationProvider { OnCreatingTicket = context => { var assertion = (context.Identity as CasIdentity)?.Assertion; if (assertion == null) { return(Task.CompletedTask); } context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, assertion.PrincipalName)); return(Task.CompletedTask); } } }); app.Use(async(context, next) => { var request = context.Request; if (request.Path.StartsWithSegments(new PathString("/login"))) { context.Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, CasDefaults.AuthenticationType); return; } if (request.Path.StartsWithSegments(new PathString("/logout"))) { context.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); } await next.Invoke(); }); app.Run(async context => { var user = context.Authentication.User; // Deny anonymous request beyond this point. if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated)) { context.Authentication.Challenge(CasDefaults.AuthenticationType); return; } // Display authenticated principal name await context.Response.WriteAsync(user.GetPrincipalName()); }); }); _client = _server.HttpClient; }
/// <summary> /// Initializes the CAS IAssertion for this instance from the first valid /// Assertion node in the CAS server response. /// </summary> /// <exception cref="TicketValidationException"> /// Thrown when data problems are encountered parsing /// the CAS server response that contains the Assertion, such as /// no valid Assertion found or no Authentication statment found in the /// the valid Assertion. /// </exception> private void ProcessValidAssertion(string response) { _logger.Debug("Unmarshalling SAML response"); var document = new XmlDocument(); document.LoadXml(response); var nsmgr = new XmlNamespaceManager(document.NameTable); nsmgr.AddNamespace("assertion", SAML11_ASSERTION_NAMESPACE); if (document.DocumentElement == null) { _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); } var assertions = document.DocumentElement.SelectNodes("descendant::assertion:Assertion", nsmgr); if (assertions == null || assertions.Count <= 0) { _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No assertions found."); } var currentTicks = _clock.UtcNow.Ticks; foreach (XmlNode assertionNode in assertions) { XmlNode conditionsNode = assertionNode.SelectSingleNode("descendant::assertion:Conditions", nsmgr); if (conditionsNode == null) { continue; } DateTime notBefore; DateTime notOnOrAfter; try { notBefore = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotBefore"); notOnOrAfter = SamlUtils.GetAttributeValueAsDateTime(conditionsNode, "NotOnOrAfter"); if (!SamlUtils.IsValidAssertion(_logger, notBefore, notOnOrAfter, currentTicks, _toleranceTicks)) { continue; } } catch (Exception) { continue; } XmlNode authenticationStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AuthenticationStatement", nsmgr); if (authenticationStmtNode == null) { _logger.Debug("No AuthenticationStatement found in SAML response."); throw new TicketValidationException("No AuthenticationStatement found in the CAS response."); } XmlNode nameIdentifierNode = assertionNode .SelectSingleNode("child::assertion:AuthenticationStatement/child::assertion:Subject/child::assertion:NameIdentifier", nsmgr); if (nameIdentifierNode == null) { _logger.Debug("No NameIdentifier found in SAML response."); throw new TicketValidationException("No NameIdentifier found in AuthenticationStatement of the CAS response."); } string subject = nameIdentifierNode.FirstChild.Value; XmlNode attributeStmtNode = assertionNode.SelectSingleNode("descendant::assertion:AttributeStatement", nsmgr); if (attributeStmtNode != null) { IDictionary<string, IList<string>> personAttributes = SamlUtils.GetAttributesFor(_logger, attributeStmtNode, nsmgr, subject); CasPrincipal = new CasPrincipal(new Assertion(subject, notBefore, notOnOrAfter, personAttributes), null, null); } else { CasPrincipal = new CasPrincipal(new Assertion(subject, notBefore, notOnOrAfter), null, null); } return; } _logger.Debug("No assertions found in SAML response."); throw new TicketValidationException("No valid assertions found in the CAS response."); }
/// <summary> /// Using ProxyTickets and the ClearPass extension for CAS CasOwaAuthHandler retrieves /// the users credentials, POSTs them to the OWA, retrieves sessionid and cdata cookies, /// sets them on the browser and redirects to the user's inbox. /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { ICasPrincipal user = context.User as ICasPrincipal; if (user == null) { throw new HttpException(500, "HttpContext.Current.User is null. Check that the DotNetCasClient is mapped and configured correctly in <web.conf>"); } // Retrieve a Proxy Ticket for ClearPass string proxyTicket = CasAuthentication.GetProxyTicketIdFor(ClearPassUrl); if (log.IsDebugEnabled) { log.Debug("Proxy ticket received for clearpass: "******"?" + ArtifactParameterName + "=" + proxyTicket + "&" + ServiceParameterName + "=" + ClearPassUrl; string clearPassResponse; try { using (StreamReader reader = new StreamReader(new WebClient().OpenRead(clearPassRequest))) clearPassResponse = reader.ReadToEnd(); } catch (Exception ex) { throw new HttpException(500, "Error getting response from clearPass at URL: " + clearPassRequest + ". " + ex.Message, ex); } string clearPass = XmlUtils.GetTextForElement(clearPassResponse, "cas:credentials"); if (String.IsNullOrEmpty(clearPass)) { throw new HttpException(500, "Received response from " + clearPassRequest + ", but cas:credientials IsNullOrEmpty. Check CAS server logs for errors. Make sure SSL certs are trusted."); } // POST username/password to owaauth.dll to get sessionid and cadata cookies var owaAuthFormFields = "destination=" + OwaUrl + "&username="******"&password="******"POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postData.Length; request.UserAgent = "Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.1;+WOW64;+Trident/5.0)"; try { using (Stream requestStream = request.GetRequestStream()) requestStream.Write(postData, 0, postData.Length); } catch (Exception ex) { if (log.IsErrorEnabled) { log.Error(ex.Message, ex); } throw new HttpException(500, "Error POSTing Auth Form to " + OwaUrl + OwaAuthPath + ". " + ex.Message, ex); } try { using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (log.IsDebugEnabled) { log.Debug("# of OWA cookies received: " + response.Cookies.Count); } // Send sessionid and cadata cookies back to the browser and redirect to Owa foreach (Cookie cookie in response.Cookies) { context.Response.Cookies.Add(new HttpCookie(cookie.Name, cookie.Value)); } string redirectUrl; if (String.IsNullOrEmpty(OwaInboxUrl)) { redirectUrl = response.GetResponseHeader("Location"); } else { redirectUrl = OwaInboxUrl; } if (log.IsDebugEnabled) { log.Debug("Added all auth cookies. Redirecting to " + redirectUrl); } context.Response.Redirect(redirectUrl); } } catch (Exception ex) { if (log.IsErrorEnabled) { log.Error(ex.Message, ex); } throw new HttpException(500, "Error getting Response from " + OwaUrl + OwaAuthPath + ". " + ex.Message, ex); } }