/// <summary>
        /// Constructs a proxy callback URL containing a ProxyCallbackParameter
        /// (proxyResponse by default).  This URL is sent to the CAS server during a proxy
        /// ticket request and is then connected to by the CAS server. If the 'CasProxyCallbackUrl' settings is specified,
        /// its value will be used to construct the proxy url. Otherwise, `ServerName` will be used.
        /// If the CAS server cannot successfully connect (generally due to SSL configuration issues), the
        /// CAS server will refuse to send a proxy ticket.
        /// </summary>
        /// <returns>the proxy callback URL to use</returns>
        public static string ConstructProxyCallbackUrl(bool gateway)
        {
            CasAuthentication.Initialize();

            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;

            EnhancedUriBuilder ub = null;

            if (CasAuthentication.CasProxyCallbackUrl != null && CasAuthentication.CasProxyCallbackUrl.Length > 0)
            {
                ub = new EnhancedUriBuilder(CasAuthentication.CasProxyCallbackUrl);
            }
            else
            {
                ub      = new EnhancedUriBuilder(CasAuthentication.ServerName);
                ub.Path = request.Url.AbsolutePath;
            }

            // Disallow dynamic parameters (see https://github.com/Jasig/dotnet-cas-client/issues/23)
            // ub.QueryItems.Add(request.QueryString);

            ub.QueryItems.Remove(CasAuthentication.TicketValidator.ArtifactParameterName);

            if (gateway)
            {
                ub.QueryItems.Set(CasAuthentication.GatewayParameterName, "true");
            }
            else
            {
                ub.QueryItems.Remove(CasAuthentication.GatewayParameterName);
            }

            return(ub.Uri.AbsoluteUri);
        }
Exemple #2
0
        /// <summary>
        /// Constructs the URL to use for redirection to the CAS server for login
        /// </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.
        /// </remarks>
        /// <returns>The redirection URL to use</returns>
        public static string ConstructLoginRedirectUrl(bool gateway, bool renew)
        {
            if (gateway && renew)
            {
                throw new ArgumentException("Gateway and Renew parameters are mutually exclusive and cannot both be True");
            }

            CasAuthentication.Initialize();

            EnhancedUriBuilder ub = new EnhancedUriBuilder(CasAuthentication.FormsLoginUrl);

            ub.QueryItems.Set(CasAuthentication.TicketValidator.ServiceParameterName, HttpUtility.UrlEncode(ConstructServiceUrl(gateway)));

            if (renew)
            {
                ub.QueryItems.Add("renew", "true");
            }
            else if (gateway)
            {
                ub.QueryItems.Add("gateway", "true");
            }

            string url = ub.Uri.AbsoluteUri;

            return(url);
        }
Exemple #3
0
        /// <summary>
        /// Determines whether the current request requires a Gateway authentication redirect
        /// </summary>
        /// <returns>True if the request requires Gateway authentication, otherwise False</returns>
        internal static bool GetRequestRequiresGateway()
        {
            CasAuthentication.Initialize();

            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;

            GatewayStatus status = CasAuthentication.GetGatewayStatus();

            bool gatewayEnabled                     = CasAuthentication.Gateway;
            bool gatewayWasNotAttempted             = (status == GatewayStatus.NotAttempted);
            bool requestDoesNotHaveGatewayParameter = !GetRequestHasGatewayParameter();
            bool cookiesRequiredUrlIsDefined        = !string.IsNullOrEmpty(CasAuthentication.CookiesRequiredUrl);
            bool requestIsNotCookiesRequiredUrl     = !GetRequestIsCookiesRequiredUrl();
            bool notAuthorizedUrlIsDefined          = !String.IsNullOrEmpty(CasAuthentication.NotAuthorizedUrl);
            bool requestIsNotAuthorizedUrl          = notAuthorizedUrlIsDefined && request.RawUrl.StartsWith(UrlUtil.ResolveUrl(CasAuthentication.NotAuthorizedUrl), true, CultureInfo.InvariantCulture);

            bool result =
                (
                    gatewayEnabled &&
                    gatewayWasNotAttempted &&
                    requestDoesNotHaveGatewayParameter &&
                    cookiesRequiredUrlIsDefined &&
                    requestIsNotCookiesRequiredUrl &&
                    !requestIsNotAuthorizedUrl
                );

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Returns a copy of the URL supplied modified to remove CAS protocol-specific
        /// URL parameters.
        /// </summary>
        /// <param name="url">The URL to remove CAS artifacts from</param>
        /// <returns>The URL supplied without CAS artifacts</returns>
        public static string RemoveCasArtifactsFromUrl(string url)
        {
            CommonUtils.AssertNotNullOrEmpty(url, "url parameter can not be null or empty.");

            CasAuthentication.Initialize();

            EnhancedUriBuilder ub = new EnhancedUriBuilder(url);

            ub.QueryItems.Remove(CasAuthentication.TicketValidator.ArtifactParameterName);
            ub.QueryItems.Remove(CasAuthentication.TicketValidator.ServiceParameterName);
            ub.QueryItems.Remove(CasAuthentication.GatewayParameterName);
            ub.QueryItems.Remove(CasAuthentication.ProxyCallbackParameterName);

            // ++ NETC-28
            Uri uriServerName;

            if (CasAuthentication.ServerName.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) ||
                CasAuthentication.ServerName.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
            {
                uriServerName = new Uri(CasAuthentication.ServerName);
            }
            else
            {
                // .NET URIs require scheme
                uriServerName = new Uri("https://" + CasAuthentication.ServerName);
            }

            ub.Scheme = uriServerName.Scheme;
            ub.Host   = uriServerName.Host;
            ub.Port   = uriServerName.Port;

            return(ub.Uri.AbsoluteUri);
        }
Exemple #5
0
        /// <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));
        }
Exemple #6
0
        /// <summary>
        /// Constructs a URL used to check the validitiy of a service ticket, with or without a proxy
        /// callback URL, and with or without requiring renewed credentials.
        /// </summary>
        /// <remarks>See CAS Protocol specification, section 2.5</remarks>
        /// <param name="serviceTicket">The service ticket to validate.</param>
        /// <param name="renew">
        /// Whether or not renewed credentials are required.  If True, ticket validation
        /// will fail for Single Sign On credentials.
        /// </param>
        /// <param name="gateway">
        /// whether or not to include gatewayResponse=true in the request (client specific).
        /// </param>
        /// <param name="customParameters">custom parameters to add to the validation URL</param>
        /// <returns>The service ticket validation URL to use</returns>
        public static string ConstructValidateUrl(string serviceTicket, bool gateway, bool renew, NameValueCollection customParameters)
        {
            if (gateway && renew)
            {
                throw new ArgumentException("Gateway and Renew parameters are mutually exclusive and cannot both be True");
            }

            CasAuthentication.Initialize();

            EnhancedUriBuilder ub = new EnhancedUriBuilder(EnhancedUriBuilder.Combine(CasAuthentication.CasServerUrlPrefix, CasAuthentication.TicketValidator.UrlSuffix));

            ub.QueryItems.Add(CasAuthentication.TicketValidator.ServiceParameterName, HttpUtility.UrlEncode(ConstructServiceUrl(gateway)));
            ub.QueryItems.Add(CasAuthentication.TicketValidator.ArtifactParameterName, serviceTicket);

            if (renew)
            {
                ub.QueryItems.Set("renew", "true");
            }

            if (customParameters != null)
            {
                for (int i = 0; i < customParameters.Count; i++)
                {
                    string key   = customParameters.AllKeys[i];
                    string value = customParameters[i];

                    ub.QueryItems.Add(key, value);
                }
            }
            return(ub.Uri.AbsoluteUri);
        }
Exemple #7
0
        /// <summary>
        /// Constructs a proxy callback URL containing a ProxyCallbackParameter
        /// (proxyResponse by default).  This URL is sent to the CAS server during a proxy
        /// ticket request and is then connected to by the CAS server. If the 'CasProxyCallbackUrl' settings is specified,
        /// its value will be used to construct the proxy url. Otherwise, `ServerName` will be used.
        /// If the CAS server cannot successfully connect (generally due to SSL configuration issues), the
        /// CAS server will refuse to send a proxy ticket.
        /// </summary>
        /// <returns>the proxy callback URL to use</returns>
        public static string ConstructProxyCallbackUrl(bool gateway)
        {
            CasAuthentication.Initialize();

            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;

            EnhancedUriBuilder ub = null;

            if (CasAuthentication.CasProxyCallbackUrl != null && CasAuthentication.CasProxyCallbackUrl.Length > 0)
            {
                ub = new EnhancedUriBuilder(CasAuthentication.CasProxyCallbackUrl);
            }
            else
            {
                ub = new EnhancedUriBuilder(CasAuthentication.ServerName);
            }
            ub.Path = request.Url.AbsolutePath;
            ub.QueryItems.Add(request.QueryString);
            ub.QueryItems.Remove(CasAuthentication.TicketValidator.ArtifactParameterName);

            if (gateway)
            {
                ub.QueryItems.Set(CasAuthentication.GatewayParameterName, "true");
            }
            else
            {
                ub.QueryItems.Remove(CasAuthentication.GatewayParameterName);
            }
            return(ub.Uri.AbsoluteUri);
        }
Exemple #8
0
        /// <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.ToLowerInvariant();
            string fileName    = request.Url.Segments[request.Url.Segments.Length - 1];

            bool contentTypeIsEligible = false;
            bool fileNameIsEligible    = true;

            foreach (string appropriateContentType in AppropriateContentTypes)
            {
                if (string.Compare(contentType, appropriateContentType, true, CultureInfo.InvariantCulture) == 0)
                {
                    contentTypeIsEligible = true;
                    break;
                }
            }

            foreach (string builtInHandler in BuiltInHandlers)
            {
                if (string.Compare(fileName, builtInHandler, true, CultureInfo.InvariantCulture) == 0)
                {
                    fileNameIsEligible = false;
                    break;
                }
            }

            // TODO: Should this be || instead of && ?
            return(contentTypeIsEligible && fileNameIsEligible);
        }
Exemple #9
0
        /// <summary>
        /// Public CasAuthenticationTicket constructor
        /// </summary>
        /// <param name="serviceTicket">CAS Service Ticket associated with this CasAuthenticationTicket</param>
        /// <param name="originatingServiceName">ServiceName used during CAS authentication/validation</param>
        /// <param name="clientHostAddress">IP address of the client initiating the authentication request</param>
        /// <param name="assertion">CAS assertion returned from the CAS server during ticket validation</param>
        public CasAuthenticationTicket(string serviceTicket, string originatingServiceName, string clientHostAddress, IAssertion assertion)
        {
            CasAuthentication.Initialize();
            Proxies = new List <string>();

            NetId                  = assertion.PrincipalName;
            ServiceTicket          = serviceTicket;
            OriginatingServiceName = originatingServiceName;
            ClientHostAddress      = clientHostAddress;
            Assertion              = assertion;

            if (DateTime.MinValue.CompareTo(assertion.ValidFromDate) != 0)
            {
                ValidFromDate = assertion.ValidFromDate;
            }
            else
            {
                ValidFromDate = DateTime.Now;
            }

            DateTime localValidUntil = ValidFromDate.Add(CasAuthentication.FormsTimeout);

            if (DateTime.MinValue.CompareTo(assertion.ValidUntilDate) != 0)
            {
                ValidUntilDate = localValidUntil.CompareTo(assertion.ValidUntilDate) < 0 ? localValidUntil : assertion.ValidUntilDate;
            }
            else
            {
                ValidUntilDate = localValidUntil;
            }
        }
Exemple #10
0
        /// <summary>
        /// Determines whether the user's browser refuses to accept session cookies
        /// </summary>
        /// <returns>True if the browser does not allow session cookies, otherwise False</returns>
        internal static bool GetUserDoesNotAllowSessionCookies()
        {
            CasAuthentication.Initialize();

            // If the request has a gateway parameter but the cookie does not
            // reflect the fact that gateway was attempted, then cookies must
            // be disabled.
            GatewayStatus status = CasAuthentication.GetGatewayStatus();

            bool gatewayEnabled                 = CasAuthentication.Gateway;
            bool gatewayWasNotAttempted         = (status == GatewayStatus.NotAttempted);
            bool requestHasGatewayParameter     = GetRequestHasGatewayParameter();
            bool cookiesRequiredUrlIsDefined    = !string.IsNullOrEmpty(CasAuthentication.CookiesRequiredUrl);
            bool requestIsNotCookiesRequiredUrl = cookiesRequiredUrlIsDefined && !GetRequestIsCookiesRequiredUrl();

            bool result =
                (
                    gatewayEnabled &&
                    gatewayWasNotAttempted &&
                    requestHasGatewayParameter &&
                    requestIsNotCookiesRequiredUrl
                );

            return(result);
        }
Exemple #11
0
        /// <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 Jasig
        /// 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;
            ub.QueryItems.Add(request.QueryString);
            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);
        }
Exemple #12
0
        /// <summary>
        /// Constructs a proxy callback URL containing a ProxyCallbackParameter 
        /// (proxyResponse by default).  This URL is sent to the CAS server during a proxy
        /// ticket request and is then connected to by the CAS server.  If the CAS server
        /// cannot successfully connect (generally due to SSL configuration issues), the
        /// CAS server will refuse to send a proxy ticket. 
        /// </summary>
        /// <remarks>
        /// This is a .NET implementation specific method used to eliminate the need for 
        /// a special HTTP Handler.  Essentially, if the client detects an incoming request
        /// with the ProxyCallbackParameter in the URL (i.e., proxyResponse), that request 
        /// is treated specially and behaves as if it were handled by an HTTP Handler.  In 
        /// other words, this behavior may or may not short circuit the request event 
        /// processing and will not allow the underlying page to execute and transmit back to
        /// the client.  If your application does coincidentally make use of the key 
        /// 'proxyResponse' as a URL parameter, you will need to configure a custom 
        /// proxyCallbackParameter value which does not conflict with the URL parameters in
        /// your application.
        /// </remarks>
        /// <returns>the proxy callback URL to use</returns>
        public static string ConstructProxyCallbackUrl()
        {
            CasAuthentication.Initialize();

            EnhancedUriBuilder ub = new EnhancedUriBuilder(ConstructProxyCallbackUrl(false));
            ub.QueryItems.Set(CasAuthentication.ProxyCallbackParameterName, "true");

            return ub.Uri.AbsoluteUri;
        }
Exemple #13
0
        /// <summary>
        /// Constructs the URL to use for redirection to the CAS server for single
        /// signout.  The CAS server will invalidate the ticket granting ticket and
        /// redirect back to the current page.  The web application must then call
        /// ClearAuthCookie and revoke the ticket from the ServiceTicketManager to sign 
        /// the client out.
        /// </summary>
        /// <returns>the redirection URL to use, not encoded</returns>
        public static string ConstructSingleSignOutRedirectUrl()
        {
            CasAuthentication.Initialize();

            // TODO: Make "logout" configurable
            EnhancedUriBuilder ub = new EnhancedUriBuilder(EnhancedUriBuilder.Combine(CasAuthentication.CasServerUrlPrefix, "logout"));
            ub.QueryItems.Set(CasAuthentication.TicketValidator.ServiceParameterName, HttpUtility.UrlEncode(ConstructServiceUrl(false)));

            return ub.Uri.AbsoluteUri;
        }
Exemple #14
0
        /// <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();

            // 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);
        }
Exemple #15
0
        /// <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;
        }
Exemple #16
0
        /// <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);
        }
Exemple #17
0
        /// <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);
        }
Exemple #18
0
        /// <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>
        /// 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);
        }
Exemple #20
0
        /// <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);
        }
Exemple #21
0
        /// <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);
        }
Exemple #22
0
        /// <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);
        }
Exemple #23
0
        /// <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);
        }
Exemple #24
0
        /// <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);
        }
Exemple #25
0
        /// <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);
        }
Exemple #26
0
        /// <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);
        }
Exemple #27
0
        /// <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;
        }
Exemple #28
0
        /// <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);
        }
        /// <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);
        }
Exemple #30
0
 /// <summary>
 /// Empty constructor (to be used during Serialization/Deserialization)
 /// </summary>
 private CasAuthenticationTicket()
 {
     CasAuthentication.Initialize();
     Proxies = new List <string>();
 }