नियंत्रक क्रिया तक पहुँचने के लिए कई भूमिकाओं की अनुमति दें


274

अभी मैं अपने कंट्रोलर एक्शन को एक्सेस करने के लिए "मेंबर्स" को अनुमति देने के लिए इस तरह से एक विधि सजाता हूं

[Authorize(Roles="members")]

मैं एक से अधिक भूमिका कैसे करूं? उदाहरण के लिए निम्नलिखित काम नहीं करता है, लेकिन यह दिखाता है कि मैं क्या करने की कोशिश कर रहा हूं ("सदस्यों" और "व्यवस्थापक" पहुंच की अनुमति दें):

[Authorize(Roles="members", "admin")] 

4
कृपया इस प्रश्न के स्वीकृत उत्तर को बदल दें। वर्तमान में स्वीकृत उत्तर वाले व्यक्ति ने यह संकेत दिया कि वह गलत था।
एरिक जे।

जवाबों:


595

एक अन्य विकल्प एक एकल अधिकृत फ़िल्टर का उपयोग करना है जैसा कि आपने पोस्ट किया था लेकिन आंतरिक कोटेशन को हटा दें।

[Authorize(Roles="members,admin")]

5
MVC 5 में भी काम करता है। +1
gkonuralp

4
ASP.NET Core 1.0 (MVC 6) और Microsoft.AspNet.Identity v3 में काम करता है। *
सोरेन

3
यह ठीक है यदि आपके पास केवल एक नियंत्रक है जिसे आपको अधिकृत करने की आवश्यकता है। यदि आपके पास एक से अधिक हैं, तो आप उन स्ट्रिंग स्थिरांक (yuck) की नकल कर रहे हैं। मैं बहुत स्थिर वर्ग को पसंद करता हूं जिसमें भूमिका नाम हैं। मेरा पालतू घृणा डुप्लिकेट तार है ... इतना बुरा।
डकैती

1
@ अच्छी खबर है कि आपने अपनी समस्या हल कर ली। अब, अपनी टिप्पणियों को हटाने पर विचार करें, कृपया
पाब्लो क्लॉस

1
क्यों? मुझे इसे पूरा करने में उम्र लग गई। यह किसी और के लिए समान समस्या का सामना करने में सहायक हो सकता है।
क्रैग

129

यदि आप कस्टम भूमिका का उपयोग करना चाहते हैं, तो आप यह कर सकते हैं:

CustomRoles वर्ग:

public static class CustomRoles
{
    public const string Administrator = "Administrador";
    public const string User = "Usuario";
}

प्रयोग

[Authorize(Roles = CustomRoles.Administrator +","+ CustomRoles.User)]

यदि आपके पास कुछ भूमिकाएँ हैं, तो शायद आप उन्हें (स्पष्टता के लिए) इस तरह से जोड़ सकते हैं:

public static class CustomRoles
{
     public const string Administrator = "Administrador";
     public const string User = "Usuario";
     public const string AdministratorOrUser = Administrator + "," + User;  
}

प्रयोग

[Authorize(Roles = CustomRoles.AdministratorOrUser)]

7
यह एक अच्छा जवाब होगा, अगर आप ऐसे लोगों को समझाते हैं जो नहीं जानते कि CustomRoles के पीछे क्या है।
जेम्स स्कीप

1
@JamesSkemp ठीक है, मैंने अपना जवाब बढ़ा दिया है। यह बहुत ही सरल है। CustumRoles एक ऐसा वर्ग है जिसे मैंने बनाया है जिसमें कुछ स्थिरांक हैं, जो मेरी एप्लिकेशन भूमिकाओं से मेल खाती है। मैंने कुछ कारणों से ऐसा किया: 1) यह वर्तनी की गलतियों से बचने के लिए 2) इंटेलीजेंस का उपयोग करने की अनुमति देता है) रखरखाव को सरल बनाने के लिए। यदि कोई भूमिका बदलती है, तो मुझे अपने आवेदन में केवल एक ही स्थान अपडेट करना होगा।
पाब्लो क्लॉस

@ पाब्लोकर वैकल्पिक रूप से आप एक झंडे विशेषता के साथ एक एनम बना सकते हैं, जैसे Convert.ToString (CustomRoles.Administrator। CustomRoles.User); कष्टप्रद हिस्सा यह है कि इसके लिए एक स्पष्ट रूपांतरण की आवश्यकता है
9

यदि आपकी 39 भूमिकाएँ हैं?
किकेनेट

मुझे लगता है कि आपकी समस्या .net से परे परमिट के मॉडलिंग के माध्यम से हो सकती है
पाब्लो क्लॉस

82

एक संभावित सरलीकरण उपवर्ग के लिए होगा AuthorizeAttribute:

public class RolesAttribute : AuthorizeAttribute
{
    public RolesAttribute(params string[] roles)
    {
        Roles = String.Join(",", roles);
    }
}

उपयोग:

[Roles("members", "admin")]

शब्दशः यह जिम शेमहिल के उत्तर के समान है।


3
यह मेरे लिए काम नहीं करता है, उपयोगकर्ता में लॉग इन विशेषता को दरकिनार करने में सक्षम था, भले ही उपयोगकर्ता के पास कोई भूमिका न हो।
यूरेलजेन

9
यह उत्तर तब बेहतर होता है जब आप स्थिरांक का उपयोग अपने मूल्यों के रूप में कर रहे हों: अर्थात [रोल्स (कांस्टेंट्स.एडमिन, कांस्टेंट.ऑनर)]
dalcam

3
यह सबसे अच्छा जवाब है
इगोरशच

18

MVC4 के लिए, अपनी भूमिकाओं के साथ Enum( UserRoles) मैं एक रिवाज का उपयोग करता हूं AuthorizeAttribute

मेरी नियंत्रित क्रिया पर, मैं करता हूं:

[CustomAuthorize(UserRoles.Admin, UserRoles.User)]
public ActionResult ChangePassword()
{
    return View();
}

और मैं एक रिवाज का उपयोग करता हूं AuthorizeAttributeजैसे:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class CustomAuthorize : AuthorizeAttribute
{
    private string[] UserProfilesRequired { get; set; }

    public CustomAuthorize(params object[] userProfilesRequired)
    {
        if (userProfilesRequired.Any(p => p.GetType().BaseType != typeof(Enum)))
            throw new ArgumentException("userProfilesRequired");

        this.UserProfilesRequired = userProfilesRequired.Select(p => Enum.GetName(p.GetType(), p)).ToArray();
    }

    public override void OnAuthorization(AuthorizationContext context)
    {
        bool authorized = false;

        foreach (var role in this.UserProfilesRequired)
            if (HttpContext.Current.User.IsInRole(role))
            {
                authorized = true;
                break;
            }

        if (!authorized)
        {
            var url = new UrlHelper(context.RequestContext);
            var logonUrl = url.Action("Http", "Error", new { Id = 401, Area = "" });
            context.Result = new RedirectResult(logonUrl);

            return;
        }
    }
}

यह फैब्रियो मार्टिनेज तामायो https://github.com/fabriciomrtnz/FNHMVC/ द्वारा संशोधित FNHMVC का हिस्सा है


1
आपकी OnAuthorization पद्धति के लिए उपयोगकर्ता को सभी सक्रिय भूमिकाओं की आवश्यकता होगी ; क्या वह जानबूझकर था, या आप उस पाश में कोई कमी नहीं छोड़ रहे हैं?
टिसन टी।

@ टायसन: मैंने बहुत बारीकी से निरीक्षण किया, यह निश्चित रूप से ऐसा लगता है कि उस पाश में एक ब्रेक की आवश्यकता होगी।
OcelotXL

@TiesonT। और @ मदरश, मैं आपके फिक्स की सराहना करता हूं, यह वास्तव में लूप के अंदर एक विराम हो सकता है। मैं ऊपर कोड बदल दूँगा।
बर्नार्डो लौरेइरो

Enum UserRoles अच्छा है। क्या आप इसे मैन्युअल रूप से घोषित करते हैं या यह डीबी की सामग्री के आधार पर ऑटोगेनेरेटेड है?
कोनराड विल्टर्स्टन

@KonradViltersten यह मैन्युअल रूप से है, लेकिन मुझे लगता है कि प्रतिबिंब और गतिशील वर्ग के साथ ऑटोजेनरेटेड किया जा सकता है
बर्नार्डो लौरेइरो

3

एक और स्पष्ट समाधान, आप कॉन्स्टेंट का उपयोग कन्वेंशन रखने के लिए और कई [ऑथराइज़] विशेषताओं को जोड़ने के लिए कर सकते हैं। इसकी जांच करें:

public static class RolesConvention
{
    public const string Administrator = "Administrator";
    public const string Guest = "Guest";
}

फिर नियंत्रक में:

[Authorize(Roles = RolesConvention.Administrator )]
[Authorize(Roles = RolesConvention.Guest)]
[Produces("application/json")]
[Route("api/[controller]")]
public class MyController : Controller

14
एकाधिक Authorizeविशेषताओं को रोजगार और शब्दार्थ और सभी शर्तों को पूरा करने की आवश्यकता होती है (यानी उपयोगकर्ता को प्रशासक और अतिथि भूमिका दोनों में होना चाहिए)।
परेशान

3

यदि आप अपने आप को उन 2 भूमिकाओं को लागू करते हुए पाते हैं, तो आप उन्हें अपने स्वयं के प्राधिकरण में लपेट सकते हैं। यह वास्तव में स्वीकृत उत्तर का विस्तार है।

using System.Web.Mvc;

public class AuthorizeAdminOrMember : AuthorizeAttribute
{
    public AuthorizeAdminOrMember()
    {
        Roles = "members, admin";
    }
}

और फिर कार्रवाई के लिए अपना नया प्राधिकरण लागू करें। मुझे लगता है कि यह साफ दिखता है और आसानी से पढ़ता है।

public class MyController : Controller
{
    [AuthorizeAdminOrMember]
    public ActionResult MyAction()
    {
        return null;
    }
}

1

एक उपवर्ग जोड़ने के साथ बेहतर कोड AuthorizeRole.cs

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    class AuthorizeRoleAttribute : AuthorizeAttribute
    {
        public AuthorizeRoleAttribute(params Rolenames[] roles)
        {
            this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)));
        }
        protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAuthenticated)
            {
                filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary {
                  { "action", "Unauthorized" },
                  { "controller", "Home" },
                  { "area", "" }
                  }
              );
                //base.HandleUnauthorizedRequest(filterContext);
            }
            else
            {
                filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary {
                  { "action", "Login" },
                  { "controller", "Account" },
                  { "area", "" },
                  { "returnUrl", HttpContext.Current.Request.Url }
                  }
              );
            }
        }
    }

इसका उपयोग कैसे करें

[AuthorizeRole(Rolenames.Admin,Rolenames.Member)]

public ActionResult Index()
{
return View();
}

1

AspNetCore 2.x का उपयोग करते हुए, आपको थोड़ा अलग तरीके से जाना होगा:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class AuthorizeRoleAttribute : AuthorizeAttribute
{
    public AuthorizeRoleAttribute(params YourEnum[] roles)
    {
        Policy = string.Join(",", roles.Select(r => r.GetDescription()));
    }
}

बस इसे इस तरह उपयोग करें:

[Authorize(YourEnum.Role1, YourEnum.Role2)]

-2
Intent promptInstall = new Intent(android.content.Intent.ACTION_VIEW);
promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
promptInstall.setDataAndType(Uri.parse("http://10.0.2.2:8081/MyAPPStore/apk/Teflouki.apk"), "application/vnd.android.package-archive" );

startActivity(promptInstall);

1
कोड सहित उत्तर में कम से कम एक मिनीमम विवरण होना चाहिए जिसमें यह बताया गया हो कि कोड कैसे काम करता है और यह प्रश्न का उत्तर क्यों देता है। फ़्यूरेटेरोड कोड कोड स्वरूपण को सुधारने की आवश्यकता है।
राबर्टो काबोनी

है ना? @ ऑइस्ट मोइल, कॉपी-पेस्ट गलत धागे में दिखता है ...
कैमरन फॉरवर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.