Esempio n. 1
0
        internal AuthenticationInternalResult Authenticate(HttpContext httpContext)
        {
            if (authenticators.Length <= 0)
            {
                return(null);
            }

            IAuthenticatorMethodCache cache = httpContext.RequestServices.GetRequiredService <IAuthenticatorMethodCache>();

            foreach (Type authenticator in authenticators)
            {
                if (AuthenticationHelper.IsValidAuthenticator(cache, authenticator, out AuthenticatorMetadata metadata))
                {
                    AuthenticationInternalResult result = AuthenticationHelper.ExecuteAuthenticator(httpContext, metadata);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }
            return(null);
        }
        // if casResult == null, the url does not contain ticket
        private static void CheckRequestUrl(HttpContext httpContext, out AuthenticationInternalResult casResult)
        {
            HttpRequest      request = httpContext.Request;
            ICASOption       option  = httpContext.RequestServices.GetRequiredService <ICASOption>();
            IQueryCollection query   = request.Query;
            string           rawurl  = request.GetDisplayUrl();

            if (query.TryGetValue("ticket", out StringValues ticketValue))
            {
                string ticket = ticketValue.ToArray()[0];
                string url    = request.GetDisplayUrl();
                // remove ticket
                url = Regex.Replace(url, @"ticket\=[^\&]+\&?", "");
                while (url[url.Length - 1] == '&' || url[url.Length - 1] == '?')
                {
                    url = url.Substring(0, url.Length - 1);
                }
                string querystr = request.QueryString.Value;
                querystr = Regex.Replace(querystr, @"ticket\=[^\&]+\&?", "");
                while (querystr.Length > 0 && (querystr[querystr.Length - 1] == '&' || querystr[querystr.Length - 1] == '?'))
                {
                    querystr = querystr.Substring(0, querystr.Length - 1);
                }
                string url_not_escaped = url;
                url = url.EscapeAll();

                string target = $"{option.ValidateUrl}?service={url}&ticket={ticket}";
                request.QueryString = new QueryString(querystr);
                // validate
                // if true, set session
                try
                {
                    HttpClient         client          = new HttpClient();
                    HttpRequestMessage validateRequest = new HttpRequestMessage()
                    {
                        Method     = HttpMethod.Get,
                        RequestUri = new Uri(target)
                    };
                    validateRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(option.ResponseAccept));
                    using (HttpResponseMessage response = client.SendAsync(validateRequest).GetAwaiter().GetResult())
                    {
                        if (response.StatusCode == System.Net.HttpStatusCode.OK)
                        {
                            string message              = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                            Type   handlerType          = option.ResponseHandler;
                            ICASResponseHandler handler = (ICASResponseHandler)ActivatorUtilities.CreateInstance(httpContext.RequestServices, handlerType);
                            IUser user = handler.Invoke(httpContext, message, url_not_escaped, out string redirect_url);
                            if (redirect_url != null)
                            {
                                casResult = new AuthenticationInternalResult(false, redirect_url, null, null);
                                return;
                            }
                            if (user == null)
                            {
                                casResult = new AuthenticationInternalResult(true, null, null, null);
                                return;
                            }
                            else
                            {
                                lock (CASLocker)
                                {
                                    if (casAuthenticatorData == null)
                                    {
                                        IAuthenticatorMethodCache cache = httpContext.RequestServices.GetRequiredService <IAuthenticatorMethodCache>();
                                        casAuthenticatorData = cache.Get(typeof(CASAuthenticator));
                                    }
                                }
                                casResult = new AuthenticationInternalResult(false, null, user, casAuthenticatorData);
                                return;
                            }
                        }
                    }
                }
                catch
                {
                    casResult = null;
                }
            }
            casResult = null;
        }
        private static AuthenticationInternalResult Authenticate(HttpContext httpContext, AuthenticationRequiredAttribute authAttribute, ICustomAttributeProvider attributeProvider)
        {
            CustomAuthenticatorsAttribute[] customAuthenticators = null;
            if (attributeProvider is TypeInfo controllerType)
            {
                customAuthenticators = GetCustomAuthenticators(controllerType);
            }
            else
            {
                customAuthenticators = attributeProvider.GetAttributes <CustomAuthenticatorsAttribute>(false);
            }
            AuthenticationInternalResult result = null;
            bool scanInherit = attributeProvider is TypeInfo;

            switch (authAttribute.Policy)
            {
            case AuthenticationPolicy.NoAuthentication:
                return(new AuthenticationInternalResult(true, null, null, null));

            case AuthenticationPolicy.All:
            {
                if (customAuthenticators.Length > 0)
                {
                    Dictionary <CustomAuthenticatorExecutionPolicy, List <CustomAuthenticatorsAttribute> > authenticatorsGroups = GroupHelper.GroupBy(customAuthenticators, ag => ag.ExecutionPolicy);
                    result = TryAuthenticate(authenticatorsGroups, CustomAuthenticatorExecutionPolicy.BeforeCAS);
                    if (result != null)
                    {
                        return(result);
                    }

                    result = ExecuteCAS(httpContext);
                    if (result != null)
                    {
                        return(result);
                    }

                    result = TryAuthenticate(authenticatorsGroups, CustomAuthenticatorExecutionPolicy.AfterCAS);
                    if (result != null)
                    {
                        return(result);
                    }
                }
                else
                {
                    result = ExecuteCAS(httpContext);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }
            break;

            case AuthenticationPolicy.CASOnly:
            {
                result = ExecuteCAS(httpContext);
                if (result != null)
                {
                    return(result);
                }
            }
            break;

            case AuthenticationPolicy.DeclaredOnly:
            {
                if (customAuthenticators.Length > 0)
                {
                    Dictionary <CustomAuthenticatorExecutionPolicy, List <CustomAuthenticatorsAttribute> > authenticatorsGroups = GroupHelper.GroupBy(customAuthenticators, ag => ag.ExecutionPolicy);
                    result = TryAuthenticate(authenticatorsGroups, CustomAuthenticatorExecutionPolicy.BeforeCAS);
                    if (result != null)
                    {
                        return(result);
                    }

                    result = TryAuthenticate(authenticatorsGroups, CustomAuthenticatorExecutionPolicy.AfterCAS);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }
            break;
            }

            return(null);

            AuthenticationInternalResult TryAuthenticate(Dictionary <CustomAuthenticatorExecutionPolicy, List <CustomAuthenticatorsAttribute> > groups, CustomAuthenticatorExecutionPolicy policy)
            {
                AuthenticationInternalResult tryResult;

                if (groups.TryGetValue(policy, out List <CustomAuthenticatorsAttribute> group))
                {
                    foreach (CustomAuthenticatorsAttribute auths in group)
                    {
                        tryResult = auths.Authenticate(httpContext);
                        if (tryResult != null)
                        {
                            return(tryResult);
                        }
                    }
                    return(null);
                }
                else
                {
                    return(null);
                }
            }
        }
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            HttpContext httpContext = context.HttpContext;
            AuthenticationInternalResult authresult = AuthenticationHelper.Authenticate(context);

            if (authresult != null)
            {
                if (authresult.IsRredirect)
                {
                    context.Result = new RedirectResult(authresult.RedirectUrl, true);
                    return;
                }
                else if (authresult.KeepUnauthenticated)
                {
                    IAuthenticationResult unauthenticatedResult = AuthenticationResult.Unauthenticated();
                    AuthenticationHelper.SaveAuthenticationResult(httpContext, unauthenticatedResult);
                    return;
                }
                else
                {
                    IAuthenticationResult authenticationResult = AuthenticationResult.Authenticated(authresult.Authenticator.Type, authresult.User);
                    AuthenticationHelper.SaveAuthenticationResult(httpContext, authenticationResult);
                    return;
                }
            }

            switch (FailedAction)
            {
            case AuthenticationFailedAction.KeepUnauthenticated:
            {
                IAuthenticationResult unauthenticatedResult = AuthenticationResult.Unauthenticated();
                AuthenticationHelper.SaveAuthenticationResult(httpContext, unauthenticatedResult);
                return;
            }

            case AuthenticationFailedAction.RedirectCAS:
                context.Result = new HttpCASRedirectResult();
                return;

            case AuthenticationFailedAction.Return403:
                context.Result = new HttpAuthenticationForbiddenResult();
                return;

            case AuthenticationFailedAction.CustomHandler:
            {
                List <Type> customAuthenticators = null;
                AuthenticationFailedHandlerAttribute[] handlers = null;
                switch (context.ActionDescriptor)
                {
                case ControllerActionDescriptor controllerActionDescriptor:
                    customAuthenticators = GetCustomAuthenticators(controllerActionDescriptor);
                    handlers             = GetCustomHandlers(controllerActionDescriptor);
                    break;

                case CompiledPageActionDescriptor compiledPageActionDescriptor:
                    customAuthenticators = GetCustomAuthenticators(compiledPageActionDescriptor);
                    handlers             = GetCustomHandlers(compiledPageActionDescriptor);
                    break;

                default:
                    throw new Exception($"not handled with action descriptor of type {context.ActionDescriptor.GetType().Name}");
                }

                if (handlers != null && handlers.Length > 0)
                {
                    IActionResult actionResult = AuthenticationHelper.ExecuteHandler(handlers[0].Handler, handlers[0].ConstructParameters, httpContext, Policy, customAuthenticators.ToArray());
                    if (actionResult != null)
                    {
                        context.Result = actionResult;
                        return;
                    }
                    else
                    {
                        // not handled
                        throw new Exception($"not handled");
                    }
                }
            }
                return;
            }
        }