PDA

View Full Version : حق دسترسی با فیلتر



z.gitaro
چهارشنبه 23 بهمن 1392, 10:17 صبح
ررول های کاربران در جدولی ثبت میشه و موقع ثبت نام کاربر رولی را انتخاب میکنه حالا من میخوام حق دسترسی به صفحات سایت رو با توجه به رول ها تعیین کنم میدونم که باید فیلتر بنویسم اما نمیدونم چطوری

hakim22
چهارشنبه 23 بهمن 1392, 10:42 صبح
یک فولدر به پروژه اضافه کنید مثلا با نام Custom و بعد به اون یک کلاس از نوع Public با نامی که باید با پسوند Attribute تموم بشه بسازید مثلا MyAuthorizeAttribute و بعد این کلاس باید از کلاس AuthorizeAtrribute ارث بری کنه مثل زیر :


public class MyAuthorizeAttribute:AuthorizeAttribute


بعد باید یک سری از متدهای کلاس مادر رو Override کنید. متدها زیادند. شما دنبال AuthorizeCore هستید.

z.gitaro
چهارشنبه 23 بهمن 1392, 11:25 صبح
مثلا کاربری میخواد بره صفحه صدور فاکتور ،به این صفحه هم فقط کاربری با رول مدیر مالی میتونه دسترسی داشته باشه حالا چطوری تو این فیلتر باید بررسی کنم که رول کاربر چیه؟

hakim22
چهارشنبه 23 بهمن 1392, 14:25 عصر
یک همچین کدی :



public class MyAuthorizeAttribute : AuthorizeAttribute
{

private readonly string _roles;
public MyAuthorizeAttribute (string roles)
{
_roles=roles;
}
protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
base.AuthorizeCore(httpContext);

bool isAuthorized =false;


var area=(string)httpContext.RouteData.DataTokens["area"];
var controller=(string)httpContext.RouteData.values["controller"];
var action=(string)httpContext.RouteData.values["action"];


IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated) {
//--- check for roles here !
isAuthorized=true;

}else
{

isAuthorized=false;

}

return isAuthorized

}


لیست role ها درون متغیر roles که یک پارامتر در متد Cunstructor کلاس است تعریف میشود ایگونه میتوانید مثل خاصیت خود Asp مقدار Role را تعیین کنید.
نام کنترلر و اکشن را میتوانید از طریق httpContext بدست آوید

متد AuthorizeCore همیشه قبل از شروع به کار یک Action اجرا میشود . چنانچه مقدار False برگردانید یعنی اینکه دسترسی مردود است و کاربر نمیتواند اکشن را اجرا کند
(بهتر است صفحه ی خطای مناسبی طراحی کنید)

فقط کافی است که با چند if نام اکشن هایی که به آن دسترسی دارد با نام اکشنی که قرار است اجرا شود بررسی کنید.

z.gitaro
پنج شنبه 24 بهمن 1392, 08:14 صبح
این namespace رو اضافه کردم اما بازم تو این خط var area = (string)httpContext.RouteData.DataTokens["area"]; RouteData رو نمیشناسه
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.Mvc;
using System.Web.Routing;
using System.Security.Principal;

hakim22
پنج شنبه 24 بهمن 1392, 09:07 صبح
من این کدهای بالا رو بدون #C نوشتم ، این رو امتحان کنید :


var rd = httpContext.Request.RequestContext.RouteData;
string currentAction = rd.GetRequiredString("action");
string currentController = rd.GetRequiredString("controller");
string currentArea = rd.Values["area"] as string;

z.gitaro
پنج شنبه 24 بهمن 1392, 09:10 صبح
ممنونم درس شد

z.gitaro
پنج شنبه 24 بهمن 1392, 09:38 صبح
اگه بخوام redirectکنم به صفحه ارور ،کدشو باید چجوری بنویسم؟

hakim22
پنج شنبه 24 بهمن 1392, 15:50 عصر
باید از کلاس RedirectToRouteResult با استفاده از new یک نمونه ی جدید بسازید و پارامترهای مورد نیازشو پر کنید.

z.gitaro
شنبه 26 بهمن 1392, 08:37 صبح
من این کد رو نوشتم بقیشو نمیدونم باید چکار کنم؟در واقع نمیدونم متغییر z رو چجوری استفاده کنم
RedirectToRouteResult z = new RedirectToRouteResult(new RouteValueDictionary { { "action", "ShowError" }, { "Controller", "Home" } });

hakim22
شنبه 26 بهمن 1392, 09:37 صبح
اولین آرگومان نام route است که بهتر است همیشه null انتخاب کنید.


RedirectToRouteResult z = new RedirectToRouteResult(null,new RouteValueDictionary { { "action", "ShowError" }, { "Controller", "Home" } });

z.gitaro
شنبه 26 بهمن 1392, 09:50 صبح
بازم کار نکرد
لازم نیس کدی شبیه این بنویسم؟
filtercontext.result=z

z.gitaro
یک شنبه 27 بهمن 1392, 08:16 صبح
hakim22 میشه اینم جواب بدین؟!
ببخشید اخه من مبتدی ام نمیدونم چی به چیه!

hakim22
یک شنبه 27 بهمن 1392, 13:15 عصر
همون مورد آخری که خودتون نوشتید باید کار بکنه ، امتحانش ضرری نداره!

z.gitaro
دوشنبه 28 بهمن 1392, 07:43 صبح
اخه ورودی این تابع httpContext هست نه filtercontext ،
httpContext هم که result نداره

hakim22
دوشنبه 28 بهمن 1392, 09:29 صبح
در اینجا شما result رو بر نمی گردونید بلکه مقدار false رو بر میگردونید.
راهی که من همیشه استفاده می کنم ساختن یک کنترلر با نام خطا و تنظیم web.config برای ارسال خطا با شماره های مختلف به این کنترلر هست به همین دلیل وقتی نتیجه ی تابع رو در اینجا false اعلام می کنم خود به خود خطای 401 به سرور اعلام میشه و صفحه ی خطا خود به خود نمایش داده میشه.

روش دوم اینکه شما در این اینجا باید یک متد دیگر رو هم در AuthorizeAttribute بازنویسی کنید :


protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "ActionName" },
{ "controller", "ControllerName" }
});
}

z.gitaro
دوشنبه 28 بهمن 1392, 11:28 صبح
واقعا ممنون hakim22
کاملا درس شد!
میگن زکات علم یاد دادنه شما زکاتتونو پرداختین!