2014-01-08 3 views
0

Я применил специальный атрибут авторизации в ASP.NET MVC4, переопределив AuthorizeAttribute, чтобы выполнить пользовательскую авторизацию. Я хочу реализовать это над определенными контроллерами и действиями контроллера, чтобы заставить их отклонять несанкционированные запросы, подобные тем, которые не вошли в систему и/или некоторые проблемы. Я не хочу, чтобы реализовать членство ASP.NET и разрешение, то это код, указанный ниже:Пользовательская авторизация ASP.NET MVC4

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(); 
     } 
     } 
} 

Это идет хорошо, пока метод OnAuthoriztion не вызывается. Проблема в том, что мои пользовательские свойства activities и roles и все остальные переменные остаются пустыми или пустыми. Я не понимаю, почему это происходит. Все эти переменные инициализируются, но все они исчезают, когда они достигают функции OnAuthorization.

ответ

0

Я нашел решение для своей проблемы самостоятельно, я применил AttributeUsage, чтобы ограничить поведение методами класса. Наряду с этим я использовал свойство AllowMultiple значение true, которое вызвало проблему, и сбросило значения моих переменных, так как при каждом выполнении переопределяет предыдущий экземпляр нового экземпляра. Установите эту переменную в false и она будет работать.

0

использование

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

Затем пользователь будет зарегистрирован и вы сможете получить доступ к usser

User.Identity.Name 

В моем случае у меня есть атрибут

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); 
    } 
} 

Так что все мои контроллеры отмеченный этим атрибутом, будет использоваться пользовательская регистрация +, если я установил AllowAnonimous, он также пропустит Auth

+0

Я просто хочу установить переменные ролей и действий, которые у меня есть при инициализации AuthorizeUserAttribute, но я получаю его значение равным нулю при вызове метода OnAuthorization. Я хочу получить значения переменных деятельности и ролей в функции AuthorizationCore, которые я начал в верхней части моего класса контроллера. – zeeshan

+0

@zeeshan можете ли вы запросить код у своего контролера? –

+0

@ Vladimir Bilyachat 'using System; с использованием System.Collections.Generic; с использованием System.Linq; с использованием System.Web; с использованием System.Web.Mvc; пространства имен TestMVC4.Controllers { [AuthorizeUser (Деятельность = "Вид", Кроль = "Пользователь")] общественного класса Default1Controller: Контроллер { // // GET:/Default1/ общественности Индекс ActionResult () { возвращение Вид(); } } ' – zeeshan

Смежные вопросы