/// <summary> /// Attempts to request a proxy ticket for the targetService specified and /// returns a URL appropriate for redirection to the targetService containing /// a ticket. /// </summary> /// <param name="targetService">The target service for proxy authentication</param> /// <param name="proxyTicketUrlParameter"> /// The name of the ticket URL parameter expected by the target service (ticket by /// default) /// </param> /// <returns>The URL of the target service with a proxy ticket included</returns> public static string GetProxyRedirectUrl(string targetService, string proxyTicketUrlParameter) { CasAuthentication.Initialize(); // Todo: Is ResolveUrl(...) appropriate/necessary? If the URL starts with ~, it shouldn't require proxy authentication string resolvedUrl = ResolveUrl(targetService); string proxyTicket = CasAuthentication.GetProxyTicketIdFor(resolvedUrl); EnhancedUriBuilder ub = new EnhancedUriBuilder(resolvedUrl); ub.QueryItems[proxyTicketUrlParameter] = proxyTicket; return ub.Uri.AbsoluteUri; }
/// <summary> /// EndRequest is used to trigger the appropriate redirection. There are /// currently three scenarios that require special redirections. /// <list> /// <item> /// Request is unauthenticated and is being routed to the FormsLoginUrl /// (typically caused by UrlAuthorizationModule). This request needs to /// be intercepted to change the 'ReturnUrl' parameter to 'serviceName' /// </item> /// <item> /// Request contains a CAS ticket in the URL. This request needs to be /// redirected back to itself without the 'ticket' parameter in order to /// avoid potential infinite automatic ticket validation loops for when /// a the ticket in the URL has expired or was revoked and the Renew /// configuration parameter is set. /// </item> /// <item> /// Request is authenticated, but is not authorized to access the /// requested resource (by UrlAuthorizationModule). If the CAS is /// configured with a NotAuthorizedUrl, the request is redirected to /// that page. Otherwise, it is redirected to the CAS login page with /// a forced 'Renew' property (to prevent infinite redirect loops). /// </item> /// </list> /// </summary> /// <param name="sender">The HttpApplication that sent the request</param> /// <param name="e">Not used</param> private static void OnEndRequest(object sender, EventArgs e) { if (!RequestEvaluator.GetRequestIsAppropriateForCasAuthentication()) { logger.Debug("EndRequest bypassed for " + HttpContext.Current.Request.RawUrl); return; } HttpContext context = HttpContext.Current; HttpRequest request = context.Request; logger.Debug("Starting EndRequest for " + request.RawUrl); if (RequestEvaluator.GetRequestRequiresGateway()) { logger.Info(" Performing Gateway Authentication"); CasAuthentication.GatewayAuthenticate(true); } else if (RequestEvaluator.GetUserDoesNotAllowSessionCookies()) { logger.Info(" Cookies not supported. Redirecting to Cookies Required Page"); CasAuthentication.RedirectToCookiesRequiredPage(); } else if (RequestEvaluator.GetRequestHasCasTicket()) { logger.Info(" Redirecting from login callback"); CasAuthentication.RedirectFromLoginCallback(); } else if (RequestEvaluator.GetRequestHasGatewayParameter()) { logger.Info(" Redirecting from failed gateway callback"); CasAuthentication.RedirectFromFailedGatewayCallback(); } else if (RequestEvaluator.GetRequestIsUnauthorized() && !String.IsNullOrEmpty(CasAuthentication.NotAuthorizedUrl)) { logger.Info(" Redirecting to Unauthorized Page"); CasAuthentication.RedirectToNotAuthorizedPage(); } else if (RequestEvaluator.GetRequestIsUnauthorized()) { logger.Info(" Redirecting to CAS Login Page (Unauthorized without NotAuthorizedUrl defined)"); CasAuthentication.RedirectToLoginPage(true); } else if (RequestEvaluator.GetRequestIsUnAuthenticated()) { logger.Info(" Redirecting to CAS Login Page"); CasAuthentication.RedirectToLoginPage(); } logger.Debug("Ending EndRequest for " + request.RawUrl); }
/// <summary> /// Determines whether the User associated with the request has been /// defined and is authenticated. /// </summary> /// <returns>True if the request has an authenticated User, otherwise False</returns> private static bool GetUserIsAuthenticated() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; bool result = ( context.User != null && context.User.Identity.IsAuthenticated ); return(result); }
/// <summary> /// Determines whether the current request is unauthenticated /// </summary> /// <returns>True if the request is unauthenticated, otherwise False</returns> internal static bool GetRequestIsUnAuthenticated() { CasAuthentication.Initialize(); bool userIsNotAuthenticated = !GetUserIsAuthenticated(); bool responseIsCasLoginRedirect = GetResponseIsCasLoginRedirect(); bool result = ( userIsNotAuthenticated && responseIsCasLoginRedirect ); return(result); }
/// <summary> /// Determines whether the request has a CAS ticket in the URL /// </summary> /// <returns>True if the request URL contains a CAS ticket, otherwise False</returns> internal static bool GetRequestHasCasTicket() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; bool result = ( request[CasAuthentication.TicketValidator.ArtifactParameterName] != null && !String.IsNullOrEmpty(request[CasAuthentication.TicketValidator.ArtifactParameterName]) ); return(result); }
/// <summary> /// Intercepts the beginning of the request pipeline. This will detect SingleSignOut /// requests. SingleSignOut requests are posted back to the serviceName URL that /// was passed when the CAS session was established. Since the behavior of the script /// at that URL is unknown, a POST back by the CAS server could have unexpected /// consequences. We want to prevent this request from authenticating and from /// executing the HttpHandler typically associated with that URL. So we are handling /// this by sending back an HTTP 200 (OK) message with a blank body and short /// circuiting all event processing and firing EndRequest directly /// (via CompleteRequest()). /// </summary> /// <param name="sender">The HttpApplication that sent the request</param> /// <param name="e">Not used</param> private static void OnBeginRequest(object sender, EventArgs e) { // Validate the ticket coming back from the CAS server (NETC-55) if (!RequestEvaluator.GetRequestIsAppropriateForCasAuthentication()) { logger.Debug("BeginRequest bypassed for " + HttpContext.Current.Request.RawUrl); return; } CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; logger.Debug("Starting BeginRequest for " + request.RawUrl); // Cleanup expired ServiceTickets in the ServiceTicketManager if (CasAuthentication.ServiceTicketManager != null) { CasAuthentication.ServiceTicketManager.RemoveExpiredTickets(); } // Cleanup expired ProxyTicket mappings in the ProxyTicketManager if (CasAuthentication.ProxyTicketManager != null) { CasAuthentication.ProxyTicketManager.RemoveExpiredMappings(); } // Detect & process inbound Single SignOut Requests from the CAS server if (CasAuthentication.ServiceTicketManager != null && CasAuthentication.ProcessIncomingSingleSignOutRequests && RequestEvaluator.GetRequestIsCasSingleSignOut()) { logger.Info("Processing inbound Single Sign Out request."); CasAuthentication.ProcessSingleSignOutRequest(); return; } // Detect & process inbound proxy callback verifications from the CAS server if (CasAuthentication.ProxyTicketManager != null && RequestEvaluator.GetRequestIsProxyResponse()) { logger.Info("Processing Proxy Callback request"); CasAuthentication.ProcessProxyCallbackRequest(); return; } logger.Debug("Ending BeginRequest for " + request.RawUrl); }
/// <summary> /// Determines whether the request is for the CookiesRequiredUrl defined in web.config /// </summary> /// <returns>True if the request is to the CookiesRequiredUrl, otherwise False</returns> private static bool GetRequestIsCookiesRequiredUrl() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; bool cookiesRequiredUrlIsDefined = !String.IsNullOrEmpty(CasAuthentication.CookiesRequiredUrl); bool requestIsCookiesRequiredUrl = cookiesRequiredUrlIsDefined && request.RawUrl.StartsWith(UrlUtil.ResolveUrl(CasAuthentication.CookiesRequiredUrl), true, CultureInfo.InvariantCulture); bool result = ( requestIsCookiesRequiredUrl ); return(result); }
/// <summary> /// Determines whether the request is an inbound proxy callback verifications /// from the CAS server /// </summary> /// <returns>True if the request is a proxy callback verificiation, otherwise False</returns> internal static bool GetRequestIsProxyResponse() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; bool requestContainsProxyCallbackParameter = !String.IsNullOrEmpty(request.QueryString[CasAuthentication.ProxyCallbackParameterName]); bool proxyCallbackParameterValueIsTrue = (request.QueryString[CasAuthentication.ProxyCallbackParameterName] == "true"); bool result = ( requestContainsProxyCallbackParameter && proxyCallbackParameterValueIsTrue ); return(result); }
/// <summary> /// Determines whether the request contains the GatewayParameterName defined in /// web.config or the default value 'gatewayResponse' /// </summary> /// <returns>True if the request contains the GatewayParameterName, otherwise False</returns> internal static bool GetRequestHasGatewayParameter() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; bool requestContainsGatewayParameter = !String.IsNullOrEmpty(request.QueryString[CasAuthentication.GatewayParameterName]); bool gatewayParameterValueIsTrue = (request.QueryString[CasAuthentication.GatewayParameterName] == "true"); bool result = ( requestContainsGatewayParameter && gatewayParameterValueIsTrue ); return(result); }
/// <summary> /// Determines whether the request is a CAS Single Sign Out request /// </summary> /// <returns>True if the request is a CAS Single Sign Out request, otherwise False</returns> internal static bool GetRequestIsCasSingleSignOut() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; bool requestIsFormPost = (request.RequestType == "POST"); bool haveLogoutRequest = !string.IsNullOrEmpty(request.Params["logoutRequest"]); bool result = ( requestIsFormPost && haveLogoutRequest ); return(result); }
/// <summary> /// Determines whether the request is appropriate for CAS authentication. /// Generally, this is true for most requests except those for images, /// style sheets, javascript files and anything generated by the built-in /// ASP.NET handlers (i.e., web resources, trace handler). /// </summary> /// <returns>True if the request is appropriate for CAS authentication, otherwise False</returns> internal static bool GetRequestIsAppropriateForCasAuthentication() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; HttpResponse response = context.Response; string contentType = response.ContentType; string fileName = request.Url.Segments[request.Url.Segments.Length - 1]; bool contentTypeIsEligible = false; bool fileNameIsEligible = true; if (string.IsNullOrEmpty(contentType) && CasAuthentication.RequireCasForMissingContentTypes) { contentTypeIsEligible = true; } if (!contentTypeIsEligible) { foreach (string appropriateContentType in CasAuthentication.RequireCasForContentTypes) { if (string.Compare(contentType, appropriateContentType, true, CultureInfo.InvariantCulture) == 0) { contentTypeIsEligible = true; break; } } } foreach (string builtInHandler in CasAuthentication.BypassCasForHandlers) { if (string.Compare(fileName, builtInHandler, true, CultureInfo.InvariantCulture) == 0) { fileNameIsEligible = false; break; } } return(contentTypeIsEligible && fileNameIsEligible); }
/// <summary> /// Determines whether the current request will be redirected to the /// CAS login page /// </summary> /// <returns>True if the request will be redirected, otherwise False.</returns> private static bool GetResponseIsCasLoginRedirect() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpResponse response = context.Response; bool requestDoesNotHaveCasTicket = !GetRequestHasCasTicket(); bool responseIsBeingRedirected = (response.StatusCode == 302); bool responseRedirectsToFormsLoginUrl = !String.IsNullOrEmpty(response.RedirectLocation) && response.RedirectLocation.StartsWith(CasAuthentication.FormsLoginUrl); bool result = ( requestDoesNotHaveCasTicket && responseIsBeingRedirected && responseRedirectsToFormsLoginUrl ); return(result); }
/// <summary> /// Determines whether the current request is unauthorized /// </summary> /// <returns>True if the request is unauthorized, otherwise False</returns> internal static bool GetRequestIsUnauthorized() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpResponse response = context.Response; bool responseIsBeingRedirected = (response.StatusCode == 302); bool userIsAuthenticated = GetUserIsAuthenticated(); bool responseIsCasLoginRedirect = GetResponseIsCasLoginRedirect(); bool result = ( responseIsBeingRedirected && userIsAuthenticated && responseIsCasLoginRedirect ); return(result); }
/// <summary> /// Determines whether the request is a return request from the /// CAS server containing a CAS ticket /// </summary> /// <returns>True if the request URL contains a CAS ticket, otherwise False</returns> internal static bool GetRequestIsCasAuthenticationResponse() { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; int artifactIndex = request.Url.AbsoluteUri.IndexOf(CasAuthentication.TicketValidator.ArtifactParameterName); bool result = ( GetRequestHasCasTicket() && artifactIndex > 0 && ( request.Url.AbsoluteUri[artifactIndex - 1] == '?' || request.Url.AbsoluteUri[artifactIndex - 1] == '&' ) ); return(result); }
public ActionResult Out() { HttpCookie ticketCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (ticketCookie != null) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(ticketCookie.Value); CasAuthenticationTicket casTicket = CasAuthentication.ServiceTicketManager.GetTicket(ticket.UserData); CasAuthentication.ServiceTicketManager.RevokeTicket(casTicket.ServiceTicket); CasAuthentication.ClearAuthCookie(); FormsAuthentication.SignOut(); Request.Cookies.Remove(FormsAuthentication.FormsCookieName); Response.Cookies.Remove(FormsAuthentication.FormsCookieName); Session.RemoveAll(); //会回调客户端 CasAuthentication.SingleSignOut(); } return(Content("退出成功,获取当前用户信息:" + User.Identity.IsAuthenticated)); }
/// <summary> /// Constructs a proxy ticket request URL containing both a proxy granting /// ticket and a URL Encoded targetServiceUrl. The URL returned will generally only /// be executed by the CAS client as a part of a proxy redirection in /// CasAuthentication.ProxyRedirect(...) or CasAuthentication.GetProxyTicketIdFor(...) /// but may also be used by applications which require low-level access to the proxy /// ticket request functionality. /// </summary> /// <param name="proxyGrantingTicketId"> /// The proxy granting ticket used to authorize the request for a proxy ticket on the /// CAS server /// </param> /// <param name="targetService"> /// The target service URL to request a proxy ticket request URL for /// </param> /// <returns>The URL to use to request a proxy ticket for the targetService specified</returns> public static string ConstructProxyTicketRequestUrl(string proxyGrantingTicketId, string targetService) { CasAuthentication.Initialize(); if (String.IsNullOrEmpty(proxyGrantingTicketId)) { throw new ArgumentException("For proxy ticket requests, proxyGrantingTicketId cannot be null and must be specified."); } if (String.IsNullOrEmpty(targetService)) { throw new ArgumentException("For proxy ticket requests, targetService cannot be null and must be specified."); } // TODO: Make "proxy" configurable. EnhancedUriBuilder ub = new EnhancedUriBuilder(EnhancedUriBuilder.Combine(CasAuthentication.CasServerUrlPrefix, "proxy")); ub.QueryItems.Add("pgt", proxyGrantingTicketId); ub.QueryItems.Add("targetService", HttpUtility.UrlEncode(targetService)); return ub.Uri.AbsoluteUri; }
/// <summary> /// Resolves a relative ~/Url to a Url that is meaningful to the /// client. /// <remarks> /// Derived from: http://weblogs.asp.net/palermo4/archive/2004/06/18/getting-the-absolute-path-in-asp-net-part-2.aspx /// </remarks> /// </summary> /// <author>J. Michael Palermo IV</author> /// <author>Scott Holodak</author> /// <param name="url">The Url to resolve</param> /// <returns>The fullly resolved Url</returns> internal static string ResolveUrl(string url) { CommonUtils.AssertNotNullOrEmpty(url, "url parameter can not be null or empty."); if (url[0] != '~') return url; CasAuthentication.Initialize(); string applicationPath = HttpContext.Current.Request.ApplicationPath; if (url.Length == 1) return applicationPath; // assume url looks like ~somePage int indexOfUrl = 1; // determine the middle character string midPath = ((applicationPath ?? string.Empty).Length > 1) ? "/" : string.Empty; // if url looks like ~/ or ~\ change the indexOfUrl to 2 if (url[1] == '/' || url[1] == '\\') indexOfUrl = 2; return applicationPath + midPath + url.Substring(indexOfUrl); }
/// <summary> /// Constructs a service URL using configured values in the following order: /// 1. if not empty, the value configured for Service is used /// - otherwise - /// 2. the value configured for ServerName is used together with HttpRequest /// data /// </summary> /// <remarks> /// The server name is not parsed from the request for security reasons, which /// is why the service and server name configuration parameters exist, per Apereo /// website. /// </remarks> /// <returns>the service URL to use, not encoded</returns> public static string ConstructServiceUrl(bool gateway) { CasAuthentication.Initialize(); HttpContext context = HttpContext.Current; HttpRequest request = context.Request; StringBuilder buffer = new StringBuilder(); if (!(CasAuthentication.ServerName.StartsWith("https://") || CasAuthentication.ServerName.StartsWith("http://"))) { buffer.Append(request.IsSecureConnection ? "https://" : "http://"); } buffer.Append(CasAuthentication.ServerName); EnhancedUriBuilder ub = new EnhancedUriBuilder(buffer.ToString()); ub.Path = request.Url.AbsolutePath; // Iterate through each of the name/value pairs in the query component of the service URL foreach (string name in request.QueryString.AllKeys) { // URL encode each name/value pair and then add it to the query items collection ub.QueryItems.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(request.QueryString[name])); } ub.QueryItems.Remove(CasAuthentication.TicketValidator.ServiceParameterName); ub.QueryItems.Remove(CasAuthentication.TicketValidator.ArtifactParameterName); if (gateway) { ub.QueryItems.Set(CasAuthentication.GatewayParameterName, "true"); } else { ub.QueryItems.Remove(CasAuthentication.GatewayParameterName); } return(ub.Uri.AbsoluteUri); }
/// <summary> /// Handles the authentication of the request. /// /// If the request contains a ticket, this will validate the ticket and create a /// FormsAuthenticationTicket and encrypted cookie container for it. It will redirect /// to remove the ticket from the URL. With Forms-based authentication, this is /// required to prevent the client from automatically/silently re-authenticating on a /// refresh or after logout. /// /// If the request does not contain a ticket, it checks for a FormsAuthentication /// cookie, decrypts it, extracts the FormsAuthenticationTicket, verifies that it /// exists in the StateProvider/ServiceTicketManager, and assigns a Principal to the /// thread and context.User properties. All events after this request become /// authenticated. /// </summary> /// <param name="sender">The HttpApplication that sent the request</param> /// <param name="e">Not used</param> private static void OnAuthenticateRequest(object sender, EventArgs e) { HttpContext context = HttpContext.Current; HttpRequest request = context.Request; // Validate the ticket coming back from the CAS server if (!RequestEvaluator.GetRequestIsAppropriateForCasAuthentication()) { logger.Debug("AuthenticateRequest bypassed for " + request.RawUrl); return; } // Validate the ticket coming back from the CAS server if (RequestEvaluator.GetRequestHasCasTicket()) { logger.Info("Processing Proxy Callback request"); CasAuthentication.ProcessTicketValidation(); } logger.Debug("Starting AuthenticateRequest for " + request.RawUrl); CasAuthentication.ProcessRequestAuthentication(); logger.Debug("Ending AuthenticateRequest for " + request.RawUrl); }
/// <summary> /// 退出 /// </summary> /// <returns></returns> public ActionResult LogOut() { HttpCookie ticketCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (ticketCookie != null) { //获取form auth令牌信息,用以进行令牌清除 FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(ticketCookie.Value); CasAuthenticationTicket casTicket = CasAuthentication.ServiceTicketManager.GetTicket(ticket.UserData); CasAuthentication.ServiceTicketManager.RevokeTicket(casTicket.ServiceTicket); CasAuthentication.ClearAuthCookie(); //移除本地cookie及session FormsAuthentication.SignOut(); Request.Cookies.Remove(FormsAuthentication.FormsCookieName); Response.Cookies.Remove(FormsAuthentication.FormsCookieName); //cas登出,调用此方法时,远端cas server会再次回调此url CasAuthentication.SingleSignOut(); } Session.RemoveAll(); return(RedirectToAction("Login", "Currency")); }
/// <summary> /// The implementation uses the CAS clearPass extension to obtain the user's password /// by requesting a proxy ticket for clearPass and parsing out the user's password that /// is returned as part of the response enclosed within <![CDATA[<cas:credentials>]]> elements. /// Returned object is a SecureString. /// </summary> public SecureString GetSecurePassword() { EnhancedUriBuilder clearPassUri = new EnhancedUriBuilder(CasAuthentication.CasServerUrlPrefix); clearPassUri.Path += "clearPass"; string proxyTicket = CasAuthentication.GetProxyTicketIdFor(clearPassUri.Uri.AbsoluteUri); if (string.IsNullOrEmpty(proxyTicket)) { throw new HttpException("Unable to obtain CAS Proxy Ticket for clearPass."); } clearPassUri.QueryItems.Add(CasClientConfiguration.Config.ArtifactParameterName, proxyTicket); var secureClearPassResponse = new SecureString(); try { var body = String.Format(CasClientConfiguration.Config.ClearPassGetRequest, clearPassUri.Uri.PathAndQuery, clearPassUri.Uri.Authority); secureClearPassResponse = SecureClient.SecureHttpRequest(clearPassUri.Uri, body, 2000); if (secureClearPassResponse.Length == 0) { throw new HttpException("ClearPass service returned an empty response."); } } catch (Exception e) { throw new HttpException( "Unable to obtain clearPass response from CAS. Review CAS logs and ensure the proxy chain is configured correctly.", e); } // Marshall into plaintext and return final var securePassword = new SecureString(); // Setup pinned variables in memory var insecureClearPassResponse = ""; var insecurePassword = ""; var unmanagedString = IntPtr.Zero; var gcHandler = GCHandle.Alloc(insecureClearPassResponse, GCHandleType.Pinned); var pwHandler = GCHandle.Alloc(insecurePassword, GCHandleType.Pinned); var ptrHandler = GCHandle.Alloc(unmanagedString, GCHandleType.Pinned); try { var xmlReaderSetting = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Auto, IgnoreWhitespace = true }; unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureClearPassResponse); insecureClearPassResponse = Marshal.PtrToStringUni(unmanagedString); if (insecureClearPassResponse == null) { throw new AccessViolationException("ClearPass response was erased from memory."); } using (TextReader stringReader = new StringReader(insecureClearPassResponse)) { using (var xmlReader = XmlReader.Create(stringReader, xmlReaderSetting)) { try { if (xmlReader.ReadToFollowing("cas:credentials")) { insecurePassword = xmlReader.ReadElementString(); foreach (char t in insecurePassword) { securePassword.AppendChar(t); } } if (securePassword.Length == 0) { throw new HttpException( "No password was received from CAS. Review clearPass configuration for CAS and ensure the feature is turned on"); } } finally { // Scrub insecure variables insecurePassword = null; insecureClearPassResponse = null; // Explicitly close and dispose xmlReader xmlReader.Close(); ((IDisposable)xmlReader).Dispose(); // Explicitly close and dispose TextReader stringReader.Close(); stringReader.Dispose(); } } } } // Ensure cleanup finally { pwHandler.Free(); gcHandler.Free(); ptrHandler.Free(); Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); } return(securePassword); }
/// <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); } }
/// <summary> /// Using CAS ProxyTickets and the ClearPass extention for CAS, CasAngelClient retrieves /// the users credentials, POSTs them to the Angel REST API ATHENICATION_PASS, retrieves /// a SSO token and URL and redirect's the user to Angel. /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { // Make sure we have an authenticated user if (!context.User.Identity.IsAuthenticated) { throw new HttpException(500, "HttpContext.Current.User is not authenticated. Check that the DotNetCasClient is mapped and configured correctly in <web.conf>"); } // Get clear text pasword via ClassPass if we are using AngelApiValidate string clearPass = ""; if (AngelApiValidate) { // Retrieve a Proxy Ticket for ClearPass string proxyTicket = CasAuthentication.GetProxyTicketIdFor(ClearPassUrl); // Get the Password from ClearPass string clearPassResponse; WebClient clearPassWebClient = null; StreamReader reader = null; try { clearPassWebClient = new WebClient(); clearPassWebClient.QueryString = new NameValueCollection { { "ticket", proxyTicket }, { "service", ClearPassUrl } }; reader = new StreamReader(clearPassWebClient.OpenRead(ClearPassUrl)); clearPassResponse = reader.ReadToEnd(); } catch (Exception ex) { throw new HttpException(500, "Error getting response from clearPass at URL: " + ClearPassUrl + ". " + ex.Message, ex); } finally { if (reader != null) { reader.Dispose(); } if (clearPassWebClient != null) { clearPassWebClient.Dispose(); } } clearPass = GetTextForElement(clearPassResponse, "cas:credentials"); if (String.IsNullOrEmpty(clearPass)) { throw new HttpException(500, "cas:credientials not found in clearPassResponse. Check CAS server logs for errors. Make sure SSL certs are trusted."); } } // Authenticate against Angel and retrieve redirect URL string strPost = "APIACTION=AUTHENTICATION_PASS&APIUSER="******"&APIPWD=" + AngelApiPassword + "&USER="******"&PASSWORD="******"&VALIDATE=" + (AngelApiValidate ? "1" : "0"); // validate forces Angel to check users credentials string angelApiResponse = PerformHttpPost(AngelApiUrl, strPost, false); string redirectUrl = GetTextForElement(angelApiResponse, "success"); if (String.IsNullOrEmpty(redirectUrl)) { throw new HttpException(500, "Angel AUTHENTICATION_PASS failed for user: "******". AngelAPI Error: " + GetTextForElement(angelApiResponse, "error")); } FormsAuthentication.SignOut(); context.Response.Redirect(redirectUrl); }
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { FormsAuthenticationTicket formsAuthTicket = CasAuthentication.GetFormsAuthenticationTicket(); CasAuthenticationTicket casTicket = CasAuthentication.ServiceTicketManager.GetTicket(formsAuthTicket.UserData); string validateUrl = EnhancedUriBuilder.Combine(CasAuthentication.CasServerUrlPrefix, "proxyValidate"); Uri url = new UriBuilder(Request.Url.Scheme, Request.Url.DnsSafeHost, ((Request.IsSecureConnection && Request.Url.Port == 443) || (!Request.IsSecureConnection && Request.Url.Port == 80)) ? -1 : Request.Url.Port, ResolveUrl("DotNetCasProxyDemoApp.application")).Uri; string proxyGrantingTicket = casTicket.ProxyGrantingTicket; string proxyUrl = UrlUtil.ConstructProxyTicketRequestUrl(casTicket.ProxyGrantingTicket, url.AbsoluteUri); string ticket; try { ticket = CasAuthentication.GetProxyTicketIdFor(url.AbsoluteUri); } catch (InvalidOperationException ioe) { ticket = "Invalid Request: " + ioe.Message; } catch (TicketValidationException tve) { ticket = "Ticket Exception: " + tve.Message; } string clickOnceValidation = validateUrl + "?service=" + Server.UrlEncode(url.AbsoluteUri) + "&proxyTicket=" + ticket; string appUrl = new UriBuilder(Request.Url.Scheme, Request.Url.DnsSafeHost, Request.Url.Port, ResolveUrl("DotNetCasProxyDemoApp.application"), "?proxyTicket=" + ticket + "&verifyUrl=" + Server.UrlEncode(validateUrl)).Uri.AbsoluteUri; StringBuilder debugText = new StringBuilder(); debugText.AppendLine("Your PGT"); debugText.AppendLine(proxyGrantingTicket); debugText.AppendLine(); debugText.AppendLine("Target Service URL"); debugText.AppendLine(url.AbsoluteUri); debugText.AppendLine(); debugText.AppendLine("Proxy Ticket URL"); debugText.AppendLine(proxyUrl); debugText.AppendLine(); debugText.AppendLine("Proxy Ticket"); debugText.AppendLine(ticket); debugText.AppendLine(); debugText.AppendLine("Validate URL"); debugText.AppendLine(validateUrl); debugText.AppendLine(); debugText.AppendLine("ClickOnce URL"); debugText.AppendLine(appUrl); debugText.AppendLine(); debugText.AppendLine("ClickOnce Validation"); debugText.AppendLine(clickOnceValidation); DebugField.Text = debugText.ToString(); ClickOnceUrl.Text = appUrl; } }
/// <summary> /// 走,登录去。。。 /// </summary> /// <returns></returns> public ActionResult GoToLogin() { if ("1".Equals(IsOpenSxLogin)) { if (User.Identity.IsAuthenticated) { string userAccount = CasAuthentication.CurrentPrincipal.Identity.Name; using (ClientSiteClientProxy proxy = new ClientSiteClientProxy(ProxyEx(Request, userAccount))) { Result <UserView> loginResult = proxy.LoginByCas(userAccount); if (loginResult.Flag == 0) { Session[ConstStr_Session.CurrentUserEntity] = loginResult.Data; LoadUserRight(loginResult.Data.RoleType.ToString(), loginResult.Data.UserId); Result <List <Base_Right> > result = proxy.LoadRightList(loginResult.Data.RoleType.ToString(), loginResult.Data.UserId); if (result.Flag == EResultFlag.Success) { var list = result.Data.Where(i => i.ParentId == 0 && i.IsMenu).ToList(); List <WebRightNode> rightNodesList = list.Select(p => new WebRightNode() { Id = p.Id, Name = p.DisplayName, Url = p.URL, Target = p.Target }).ToList(); foreach (var rightNode in rightNodesList) { rightNode.ChildNode = GetChildNode(rightNode.Id, result.Data); } Session[ConstStr_Session.CurrUserRight] = rightNodesList; ClientProxyExType cpet = new ClientProxyExType(); cpet = new ClientProxyExType(); cpet.UserID = loginResult.Data.UserId.ToString(); cpet.IP_Client = Request.UserHostAddress; cpet.IP_WebServer = NetTools.GetLocalMachineIP4(); cpet.CurrentUser = loginResult.Data; Session[ConstStr_Session.CurrentProxyExType] = cpet; } } } string url = "Home/SignIndex"; if (Request.QueryString.AllKeys.Contains("returnUrl")) { url = Request.QueryString["returnUrl"]; } return(Redirect(url)); } else { CasAuthentication.RedirectToLoginPage(); Response.Write("你不登录?"); Response.End(); } } else { return(RedirectToAction("Login")); } return(View()); }
protected void OutstandingTickets_RowCommand(object sender, GridViewCommandEventArgs e) { int index = int.Parse(e.CommandArgument.ToString()); string ticket = null; if (OutstandingTickets != null && OutstandingTickets.DataKeys != null && OutstandingTickets.DataKeys[index] != null) { ticket = (OutstandingTickets.DataKeys[index].Values["ServiceTicket"].ToString()); } bool isMyTicket = false; IEnumerable <string> allMyTickets = CasAuthentication.ServiceTicketManager.GetUserServiceTickets(HttpContext.Current.User.Identity.Name); foreach (string myTicket in allMyTickets) { if (myTicket == ticket) { isMyTicket = true; break; } } if (e.CommandName == "Revoke") { CasAuthentication.ServiceTicketManager.RevokeTicket(ticket); if (isMyTicket) { CasAuthentication.ClearAuthCookie(); } Page.Response.Redirect(Request.RawUrl, false); } else if (e.CommandName == "SSO") { string samlString = @"<samlp:LogoutRequest ID=""" + new Random().Next(10000) + @""" Version=""2.0"" IssueInstant=""" + DateTime.Now + @""">" + @"<saml:NameID>@NOT_USED@</saml:NameID>" + @"<samlp:SessionIndex>" + ticket + "</samlp:SessionIndex>" + @"</samlp:LogoutRequest>"; string request = "logoutRequest=" + Server.UrlEncode(samlString); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Page.Request.Url.ToString()); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = request.Length; using (Stream requestStream = req.GetRequestStream()) { using (StreamWriter requestStreamWriter = new StreamWriter(requestStream)) { requestStreamWriter.Write(request); } } HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); using (Stream responseStream = resp.GetResponseStream()) { using (StreamReader responseStreamReader = new StreamReader(responseStream)) { string responseBody = responseStreamReader.ReadToEnd(); ResponseField.Text = responseBody; } } Response.Redirect(Request.RawUrl); } }
/// <summary> /// Logs the user off (from CAS). As of now, this will take you to the CAS logout page by default. /// </summary> /// <returns></returns> public ActionResult LogOff() { CasAuthentication.SingleSignOut(); return(RedirectToAction("Index", "Home")); }
/// <summary> /// Empty constructor (to be used during Serialization/Deserialization) /// </summary> private CasAuthenticationTicket() { CasAuthentication.Initialize(); Proxies = new List <string>(); }