Question

J'ai mis en œuvre personnalisée de l'autorisation de l'attribut ASP.NET MVC4 en remplaçant la AuthorizeAttribute faire la coutume de l'autorisation.Je veux mettre en œuvre cette sur certains contrôleurs et actions de contrôleur pour les faire rejeter les requêtes non autorisées, comme celui de l'utilisateur n'est pas connecté et/ou de certains droits en question.Je ne veux pas mettre en œuvre la asp.net l'adhésion et l'autorisation, le code est donné ci-dessous :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics.CodeAnalysis;
using System.Security.Principal;
using System.Web.Mvc.Properties;
using System.Web.Routing;

namespace TestMVC4
{
    public sealed class AuthorizeUserAttribute : AuthorizeAttribute
    {
        private static readonly string[] _emptyArray = new string[0];
        string activities;
        string[] activitiesList = _emptyArray;

        string roles;
        string[] rolesList = new string[0];

        /// <summary>
        /// Gets or sets list of authorized activities 
        /// </summary>
        public string Activities
        {
            get { return activities ?? String.Empty; }
            set
            {
                activities = value;
                activitiesList = SplitString(value);
            }
         }

         public string CRole
         {
            get { return roles ?? String.Empty; }
            set
            {
                 roles = value;
                 rolesList = SplitString(value);
             }
         }

        /// <summary>
        /// Authorization initial call
        /// </summary>
        /// <param name="filterContext">Filter context</param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
            {
                // If a child action cache block is active, we need to fail immediately, even if authorization
                // would have succeeded. The reason is that there's no way to hook a callback to rerun
                // authorization before the fragment is served from the cache, so we can't guarantee that this
                // filter will be re-run on subsequent requests.
                //throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
                throw new InvalidOperationException("Cannot use within child action cache.");
            }

            bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
                                     || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);

            if (skipAuthorization)
            {
                return;
            }

            if (AuthorizeCore(filterContext.HttpContext))
            {
                // ** IMPORTANT **
                // Since we're performing authorization at the action level, the authorization code runs
                // after the output caching module. In the worst case this could allow an authorized user
                // to cause the page to be cached, then an unauthorized user would later be served the
                // cached page. We work around this by telling proxies not to cache the sensitive page,
                // then we hook our custom authorization code into the caching mechanism so that we have
                // the final say on whether a page should be served from the cache.

                HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
                cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
            }
            else
            {
                HandleUnauthorizedRequest(filterContext);
            }
        }

        /// <summary>
        /// Main method for overriding custom authorization for application
        /// </summary>
        /// <param name="httpContext">Current execution context</param>
        /// <returns>True/False whether user is authorized for given activity or not respectively</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            //Verify sessionuser roles
            if (rolesList != null)
            {
                String sessionRole = Convert.ToString(httpContext.Session["MyRole"]);

                foreach (String role in rolesList)
                {
                    if (role == sessionRole)
                        return true;
                }
            }

            //IPrincipal user = httpContext.User;
            //if (!user.Identity.IsAuthenticated)
            //{
            //    return false;
            //}

            //if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
            //{
            //    return false;
            //}

            //if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
            //{
            //    return false;
            //}

            return false;
        }

        /// <summary>
        /// Overriden method for handling unauthorized request routing
        /// </summary>
        /// <param name="filterContext">Authorization context for which the request has been made</param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
            filterContext.Result = new HttpUnauthorizedResult();

            //filterContext.RequestContext.RouteData;

            //filterContext.Result = new RedirectToRouteResult(
            //        new RouteValueDictionary(
            //            new
            //            {
            //                controller = "Error",
            //                action = "Unauthorised"
            //            })
            //        );
        }

        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
        }

        protected HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            bool isAuthorized = AuthorizeCore(httpContext);
            return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
        }

        /// <summary>
        /// Splits the string on commas and removes any leading/trailing whitespace from each result item.
        /// </summary>
        /// <param name="original">The input string.</param>
        /// <returns>An array of strings parsed from the input <paramref name="original"/> string.</returns>
        string[] SplitString(string original)
        {
            if (String.IsNullOrEmpty(original))
            {
                return _emptyArray;
            }

            var split = from piece in original.Split(',')
                        let trimmed = piece.Trim()
                        where !String.IsNullOrEmpty(trimmed)
                        select trimmed;
            return split.ToArray();
        }
      }
}  

Il va bien jusqu'à ce que le OnAuthoriztion la méthode est invoquée.Le problème est que mon propriétés personnalisées activities et roles et toutes les autres variables va vide ou nulle, je ne comprends pas pourquoi ce qui se passe.L'ensemble de ces variables est initialisé, mais ils vont tous nuls quand il atteint le OnAuthorization fonction.

Était-ce utile?

La solution 2

J'ai trouvé la solution à mon problème par moi-même, j'ai appliqué AttributeUsage pour limiter le comportement de méthodes de la classe.Avec ce que j'ai utilisé son AllowMultiple true à la propriété qui a causé le problème et fait mes valeurs de variables de réinitialisation, car il utilise une nouvelle instance à chaque exécution remplaçant la précédente.Définissez cette variable à false et ça a fonctionné.

Autres conseils

utilisation

 Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(userName),
                                new string[] {"Roles goes here"});

Alors l'utilisateur sera connecté et vous serez en mesure d'accéder à usser

User.Identity.Name

Dans mon cas, j'ai attribut

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
{

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (Thread.CurrentPrincipal.Identity.Name.Length == 0)
        {
                    if (ValidateUser(userName, password))
                        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(userName, "Basic"),
                            new string[] {});

        }
        return base.IsAuthorized(actionContext);
    }
}

De sorte que tous mes contrôleurs marqué avec cet attribut devra utiliser des logining + si j'ai mis AllowAnonimous il va également passer Auth

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top