SORU
29 Ocak 2011, CUMARTESİ


ASP.NET MVC - Rol Sağlayıcısı için Alternatif?

Deniyorum önlemek için kullanın Rolü Sağlayıcı ve Üyelik Sağlayıcısı kuruluşundan beri çok hantal bana göre, ve bu nedenle ben sadece kendi yapmadan "sürüm" hangisi daha az hantal ve daha yönetilebilir/esnek. Şimdi benim sorum.. iyi hangi Rol Sağlayıcısı için bir alternatif var mı? (Provier, üyelik sağlayıcısı vb özel Rol yapabileceğimi biliyorum.)

Daha yönetilebilir/esnek yani ben sınırlı kullanın Roller statik sınıf ve uygulamak doğrudan içine benim hizmet katmanı olan etkileşim ile veritabanı içeriği, yerine ben bağlı kullanın Roller statik sınıfı, kendi veritabanı içeriği vb de tablo adları korkunç..

Şimdiden teşekkürler.

CEVAP
29 Ocak 2011, CUMARTESİ


Seninle aynı durumda değilim - her zaman RoleProviders nefret ettim. Evet, eğer bir şeyler elde etmek için bir küçük isterseniz büyük demektirweb sitesiçok gerçekçi değil ama. Her zaman buldum büyük dezavantajı onlar doğrudan ASP.NET sen kravat.

Bu şekilde gittiğim için yeni bir proje olduğunu tanımlayan birkaç arayüzleri olursunuz. hizmet katmanı (NOT: ben basitleştirilmiş bu biraz - ama sen-ebil kolayca eklemek için onları):

public interface IAuthenticationService
{
    bool Login(string username, string password);
    void Logout(User user);
}

public interface IAuthorizationService
{
    bool Authorize(User user, Roles requiredRoles);
}

Kullanıcılarınız Roles bir sıralama olabilir:

public enum Roles
{
    Accounting = 1,
    Scheduling = 2,
    Prescriptions = 4
    // What ever else you need to define here.
    // Notice all powers of 2 so we can OR them to combine role permissions.
}

public class User
{
    bool IsAdministrator { get; set; }
    Roles Permissions { get; set; }
}

Senin için IAuthenticationService standart parola denetimi yapan bir temel uygulama olabilir ve daha sonra biraz çerez vb ayarı, böyle yapan FormsAuthenticationService olabilir. Senin için AuthorizationService, böyle bir şeye ihtiyacınız olur:

public class AuthorizationService : IAuthorizationService
{
    public bool Authorize(User userSession, Roles requiredRoles)
    {
        if (userSession.IsAdministrator)
        {
            return true;
        }
        else
        {
            // Check if the roles enum has the specific role bit set.
            return (requiredRoles & user.Roles) == requiredRoles;
        }
    }
}

Bu temel hizmetler üzerinde, kolayca vb şifreleri yeniden hizmetleri ekleyebilirsiniz.

MVC kullanıyorsanız bu yana, eylem düzeyi ActionFilter kullanarak yetkilendirme yapabilirsiniz:

public class RequirePermissionFilter : IAuthorizationFilter
{
    private readonly IAuthorizationService authorizationService;
    private readonly Roles permissions;

    public RequirePermissionFilter(IAuthorizationService authorizationService, Roles requiredRoles)
    {
        this.authorizationService = authorizationService;
        this.permissions = requiredRoles;
        this.isAdministrator = isAdministrator;
    }

    private IAuthorizationService CreateAuthorizationService(HttpContextBase httpContext)
    {
        return this.authorizationService ?? new FormsAuthorizationService(httpContext);
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var authSvc = this.CreateAuthorizationService(filterContext.HttpContext);
        // Get the current user... you could store in session or the HttpContext if you want too. It would be set inside the FormsAuthenticationService.
        var userSession = (User)filterContext.HttpContext.Session["CurrentUser"];

        var success = authSvc.Authorize(userSession, this.permissions);

        if (success)
        {
            // Since authorization is performed 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 or not a page should be served from the cache.
            var cache = filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(new TimeSpan(0));
            cache.AddValidationCallback((HttpContext context, object data, ref HttpValidationStatus validationStatus) =>
            {
                validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
            }, null);
        }
        else
        {
            this.HandleUnauthorizedRequest(filterContext);
        }
    }

    private void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // Ajax requests will return status code 500 because we don't want to return the result of the
        // redirect to the login page.
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new HttpStatusCodeResult(500);
        }
        else
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }

    public HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        var authSvc = this.CreateAuthorizationService(httpContext);
        var userSession = (User)httpContext.Session["CurrentUser"];

        var success = authSvc.Authorize(userSession, this.permissions);

        if (success)
        {
            return HttpValidationStatus.Valid;
        }
        else
        {
            return HttpValidationStatus.IgnoreThisRequest;
        }
    }
}

O zaman denetleyici eylemleri üzerine: süslemek

[RequirePermission(Roles.Accounting)]
public ViewResult Index()
{
   // ...
}

Bu yaklaşımın avantajı da bağımlılık enjeksiyon ve şeyler Tel IoC bir kap kullanabilirsiniz. Ayrıca, birden çok uygulama (sadece senin ASP.NET bir) boyunca kullanabilirsiniz. ORM uygun şema tanımlamak için kullanırsınız.

Eğer FormsAuthorization/Authentication hizmetler hakkında daha fazla bilgi ihtiyacınız varsa ya buradan nereye, bana haber ver.

EDİT: "Güvenlik", bir HtmlHelper. ile bunu yapabilirsin süsleme eklemek İçin Bu muhtemelen biraz daha fazla ihtiyacı var. ama siz anladınız.

public static bool SecurityTrim<TModel>(this HtmlHelper<TModel> source, Roles requiredRoles)
{
    var authorizationService = new FormsAuthorizationService();
    var user = (User)HttpContext.Current.Session["CurrentUser"];
    return authorizationService.Authorize(user, requiredRoles);
}

Ve sonra iç görünüm (burada Razor sözdizimini kullanarak):

@if(Html.SecurityTrim(Roles.Accounting))
{
    <span>Only for accounting</span>
}

EDİT: UserSession Bu gibi bir şey olacaktır

public class UserSession
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public bool IsAdministrator { get; set; }
    public Roles GetRoles()
    {
         // make the call to the database or whatever here.
         // or just turn this into a property.
    }
}

Bu şekilde, şifre karma duyurmak ve onlar bu yana geçerli kullanıcının oturum içindeki tüm diğer ayrıntıları bilmiyoruzgerçektenkullanıcının oturum süresi için gerekli değil.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • OnlyFunClips

    OnlyFunClips

    16 ŞUBAT 2012
  • SelmerSaxMan

    SelmerSaxMan

    24 HAZİRAN 2006
  • The White House

    The White Ho

    21 Ocak 2006