تعیین سطح دسترسی کاربران (بصورت جزئی به اجزا سایت) در Asp.Net

یکشنبه 24 خرداد 1394

در این مقاله قصد داریم تعیین سطح دسترسی هر کار بر صورت جداگانه به عناصر صفحات و خود صفحات را به صورت داینامیک و در لحظه اجرا یاد بدیم .

تعیین سطح دسترسی کاربران (بصورت جزئی به اجزا سایت) در Asp.Net

ابتدا باید جداول مورد نظر را بسازیم

یک بانک اطلاعاتی با نام User_Permission_DB ایجاد میکنیم

یک جدول برای نگهداری اطلاعات ورود کاربران با نام Users ایجاد میکنیم

سپس یک جدول با نام Permissions برای نگهداری اطلاعات مربوط به کنترل ها و صفحات میسازیم

در این جدول ستون ParentID برای نگهداری والد این رکورد میباشد

مثلا صفحه کاربران چند زیر مجموعه دارد با عنوان های ثبت کاربر جدید و ویرایش و ... با این ستون میتونیم مشخص کنیم که این Permission برای کدام یک از صفحات یا کنترل اصلی می باشد

- سپس یک جدول برای نگهداری دسترسی هر کاربر با نام Users_Permissions می سازیم

را بطه این جدول با Users و Permissions را بر قرار میکنیم

 

اسکریپت ساخت بانک اطلاعاتی به همراه جداول به شرح ذیل است :

ابتدا بانکی با نام User_Permission_DB بسازید و اسکریپت زیر را روی آن اجرا کنید


USE [User_Permission_DB]
GO
/****** Object:  Table [dbo].[Users]    Script Date: 06/13/2015 16:09:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
	[UserID] [int] IDENTITY(1,1) NOT NULL,
	[UserName] [nvarchar](150) NOT NULL,
	[Password] [nvarchar](150) NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
	[UserID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Users] ON
INSERT [dbo].[Users] ([UserID], [UserName], [Password]) VALUES (1, N'ایمان مدائنی', N'123')
INSERT [dbo].[Users] ([UserID], [UserName], [Password]) VALUES (2, N'برنامه نویسان', N'123')
SET IDENTITY_INSERT [dbo].[Users] OFF
/****** Object:  Table [dbo].[Permissions]    Script Date: 06/13/2015 16:09:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Permissions](
	[PermissionID] [int] IDENTITY(1,1) NOT NULL,
	[PermissionTitle] [nvarchar](150) NOT NULL,
	[ParentID] [int] NULL,
 CONSTRAINT [PK_Permissions] PRIMARY KEY CLUSTERED 
(
	[PermissionID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Permissions] ON
INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (1, N'پنل مدیریت', NULL)
INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (2, N'صفحه مدیریت کاربران', NULL)
INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (3, N'افزودن کاربر جدید', 2)
INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (4, N'تعیین سطح دسترسی', 2)
SET IDENTITY_INSERT [dbo].[Permissions] OFF
/****** Object:  Table [dbo].[Users_Permissions]    Script Date: 06/13/2015 16:09:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users_Permissions](
	[UP_ID] [int] IDENTITY(1,1) NOT NULL,
	[UserID] [int] NOT NULL,
	[PermissionID] [int] NOT NULL,
 CONSTRAINT [PK_Users_Permissions] PRIMARY KEY CLUSTERED 
(
	[UP_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Users_Permissions] ON
INSERT [dbo].[Users_Permissions] ([UP_ID], [UserID], [PermissionID]) VALUES (7, 1, 1)
INSERT [dbo].[Users_Permissions] ([UP_ID], [UserID], [PermissionID]) VALUES (8, 1, 4)
SET IDENTITY_INSERT [dbo].[Users_Permissions] OFF
/****** Object:  ForeignKey [FK_Users_Permissions_Permissions]    Script Date: 06/13/2015 16:09:29 ******/
ALTER TABLE [dbo].[Users_Permissions]  WITH CHECK ADD  CONSTRAINT [FK_Users_Permissions_Permissions] FOREIGN KEY([PermissionID])
REFERENCES [dbo].[Permissions] ([PermissionID])
GO
ALTER TABLE [dbo].[Users_Permissions] CHECK CONSTRAINT [FK_Users_Permissions_Permissions]
GO
/****** Object:  ForeignKey [FK_Users_Permissions_Users]    Script Date: 06/13/2015 16:09:29 ******/
ALTER TABLE [dbo].[Users_Permissions]  WITH CHECK ADD  CONSTRAINT [FK_Users_Permissions_Users] FOREIGN KEY([UserID])
REFERENCES [dbo].[Users] ([UserID])
GO
ALTER TABLE [dbo].[Users_Permissions] CHECK CONSTRAINT [FK_Users_Permissions_Users]
GO

حالا یک پروژه با نام PermissionUsers_Example_Asp ایجاد میکنیم

ابتدا یک MasterPage برای مدیریت سایت با نام Admin.Master ایجاد میکنیم

یک دایرکتوری برای قرار دادن صفحات مدیریتی با نام AdminPanel ایجاد میکنیم

 

ابتدا باید صفحه مدیریت کاربران و تعیین سطح دسترسی آنها را بسازیم ، پس در پوشه AdminPanel یک صفحه که از Admin.Master پیروی میکند با نام ManageUsers میسازیم

 

در این صفحه یک MultiView به همراه  3 عدد  View قرار میدیم

1 - vmUsers برای نمایش لیست کاربران

2- vmAddEditUser برای افرودن و ویرایش کاربر جدید

3- vmPermissions برای تعیین سطح هر کاربر

 

ابتدا با لیست کاربران شروع میکنیم

یک SqlDataSource و یک GridView داخل vmUsers قرار میدیم

و یک ستون از جنس TemplateField برای قرار دادن گزینه تعیین دسترسی داخل آن قرار میدیم

 

 

در قسمت vmAddEditUser باید کاربر جدید را ثبت کنیم پس یک جدول و فیلد های مورد نظر را ایجاد میکنیم

کد های ثبت کاربر به شرح ذیل است

        protected void btnAddUser_Click(object sender, EventArgs e)
        {
            string query = "Insert Into Users (Username,Password) Values (@Username,@Password)";

            SqlCommand command = new SqlCommand(query, connection);
            command.Parameters.AddWithValue("@Username", txtUserName.Text);
            command.Parameters.AddWithValue("@Password", txtPass.Text);
            connection.Open();
            command.ExecuteNonQuery();
            connection.Close();

            gvUsers.DataBind();
            mvUsers.SetActiveView(vmUsers);
        }

 

سپس در vmPermission یک TreeView قرار میدیم برای نمایش دسترسی ها و در رویداد RoeCommand گرید ویو کنترل را از بانک پر میکنیم

        protected void gvUsers_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            int UserID = int.Parse(e.CommandArgument.ToString());

            DataTable dt = this.GetData("Select * From Permissions Where ParentID is null");
            this.PopulateTreeView(dt, 0, null);
            UserPermissions(UserID);
            tvPermission.ExpandAll();
            ViewState["UserID"] = UserID;
            mvUsers.SetActiveView(vmPermission);
        }

 

در قسمت اول کد با استفاده از CommandArgument کد کاربر را بدست میاریم

 int UserID = int.Parse(e.CommandArgument.ToString());

 

در قسمت بعدی یک DataTable را با استفاده متد GetData پر میکنیم

        private DataTable GetData(string query)
        {
            DataTable dt = new DataTable();

            using (SqlCommand cmd = new SqlCommand(query))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.Connection = connection;
                    sda.SelectCommand = cmd;
                    sda.Fill(dt);
                }
            }
            return dt;

        }

 

متد بالا با استفاده از کوئری ورودی یک DataTable را برمی گرداند .

متد PopulateTreeView وظیفه پر کردن TreeView را برعهده دارد

        private void PopulateTreeView(DataTable dtParent, int parentId, TreeNode treeNode)
        {
            foreach (DataRow row in dtParent.Rows)
            {
                TreeNode child = new TreeNode
                {
                    Text = row["PermissionTitle"].ToString(),
                    Value = row["PermissionID"].ToString()
                };
                if (parentId == 0)
                {
                    tvPermission.Nodes.Add(child);
                    DataTable dtChild = this.GetData("SELECT PermissionID, PermissionTitle FROM Permissions WHERE ParentID = " + child.Value);
                    PopulateTreeView(dtChild, int.Parse(child.Value), child);
                }
                else
                {
                    treeNode.ChildNodes.Add(child);
                }
            }
        }

 

و متد UserPermissions وظیفه انتخاب سطح دسترسی های کاربر جاری را بر عهده دارد

        void UserPermissions(int userID)
        {
            SqlCommand command = new SqlCommand("Select * From  Users_Permissions Where UserID=@UserID and PermissionID=@PermissionID",connection);
            command.Parameters.Add(new SqlParameter("@UserID", 0));
            command.Parameters.Add(new SqlParameter("@PermissionID", 0));
            connection.Open();
            foreach (TreeNode node in tvPermission.Nodes)
            {
 

                command.Parameters["@UserID"].Value = userID;
                command.Parameters["@PermissionID"].Value = node.Value;
                using (SqlDataReader dr = command.ExecuteReader())
                {
                    if (dr.HasRows)
                    {
                        node.Checked = true;
                    }
                }

                foreach (TreeNode childNode in node.ChildNodes)
                {
                    command.Parameters["@UserID"].Value = userID;
                    command.Parameters["@PermissionID"].Value = childNode.Value;
                    using (SqlDataReader dr = command.ExecuteReader())
                    {
                        if (dr.HasRows)
                        {
                            childNode.Checked = true;
                        }
                    }
                }
               
                
            }
            connection.Close();
        }

در نهایت در کلید ثبت دسترسی ،  ابتدا تمام دسترسی ها کاربر را حذف کرده و مجدد ثبت میکنیم

        protected void Button2_Click(object sender, EventArgs e)
        {
            int UserID = int.Parse(ViewState["UserID"].ToString());
            SqlCommand command = new SqlCommand();
            command.Connection = connection;
            command.CommandText = "Delete From Users_Permissions Where UserID=" + UserID;
            connection.Open();
            command.ExecuteNonQuery();
            command.CommandText =
"Insert Into Users_Permissions (UserID,PermissionID) Values (@UserID,@PermissionID)";
            command.Parameters.Add(new SqlParameter("@UserID", 0));
            command.Parameters.Add(new SqlParameter("@PermissionID", 0));
            foreach (TreeNode checkedNode in tvPermission.CheckedNodes)
            {

                command.Parameters["@UserID"].Value = UserID;
                command.Parameters["@PermissionID"].Value = checkedNode.Value;
                command.ExecuteNonQuery();
            }
            connection.Close();
        }

حالا میتوانیم دسترسی را به کاربر بدهیم

 

اطلاعات را به صورت دستی وارد جدول Permissions میکنیم

 

 

سپس با باز کردن فرم و زدن کلید دسترسی میتوانیم دسترسی کاربر را تعیین کنیم

 

حالا باید یک صفحه برای ورود کاربران بسازیم به عنوان Login

 

کد های لاگین کردن کاربر به شرح ذیل است

        protected void btnAddUser_Click(object sender, EventArgs e)
        {
            using (
    SqlConnection connection =
        new SqlConnection(
            System.Configuration.ConfigurationManager.ConnectionStrings["User_Permission_DBConnectionString"
                ].ConnectionString)
    )
            {


                SqlCommand command =
                    new SqlCommand(
                        "Select * From  Users Where Username=@Username and Password=@Password",
                        connection);
                command.Parameters.AddWithValue("@Username", txtUserName.Text);
                command.Parameters.AddWithValue("@Password", txtPass.Text);
                connection.Open();
                SqlDataReader dr = command.ExecuteReader();
                if (dr.Read())
                {
                    string UserID = dr[0].ToString();
                   FormsAuthentication.RedirectFromLoginPage(UserID,false);
                }
               connection.Close();
            }
        }

 

کتابخانه FormsAuthentication وظیفه اهراز هویت و لاگین نگه داشتم کاربر را برعهده دارد

 

در نهایت باید اهراز هویت را روی پروژه خود فعال کنیم

این کار از طریق web.config انجام میشود

      <authentication mode="Forms">
        <forms name="barnamenevisan" defaultUrl="/" loginUrl="/Login.aspx" timeout="43200"/>
      </authentication>

 

و حالا برای چک کردن دسترسی کاربران یک کلاس با نام CheckPermission و یک متد static با نام Check میسازم

این متد کد دسترسی را دریافت میکند و یک متغیر از نوع bool برمیگرداند که آیا کاربر دسترسی دارد یا خیر

 

        public static bool Check(int PermissionID)
        {
            using (
                SqlConnection connection =
                    new SqlConnection(
                        System.Configuration.ConfigurationManager.ConnectionStrings["User_Permission_DBConnectionString"
                            ].ConnectionString)
                )
            {


                SqlCommand command =
                    new SqlCommand(
                        "Select * From  Users_Permissions Where UserID=@UserID and PermissionID=@PermissionID",
                        connection);
                command.Parameters.AddWithValue("@UserID", int.Parse(HttpContext.Current.User.Identity.Name));
                command.Parameters.AddWithValue("@PermissionID", PermissionID);
                connection.Open();
                SqlDataReader dr = command.ExecuteReader();

                if (dr.HasRows)
                {
                    return true;
                }
                return false;
               
            }

        }

 

برای بدست آوردن کاربر جاری از HttpContext.Current.User.Identity.Name استفاده کرده ایم .

در اینجا دیگه میتونیم دسترسی ها را کنترل کنیم

در رویداد لود مسترپیج ادمین چک میکنیم که کاربر دسترسی به ادمین دارد یا خیر

        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if(!CheckPermission.Check(1))
                 Response.Redirect("/Login.aspx");
            }
            else
            {
                Response.Redirect("/Login.aspx");
            }
        }

برای دکمه ها هم از روش زیر استفاده میکنیم

        protected void Page_Load(object sender, EventArgs e)
        {
            Button1.Visible = CheckPermission.Check(3);
        }

در قسمت visible کلاس CheckPermission را فراخوانی کردم

برای دکمه های داخل کنترل گرید هم از روش زیر اصتفاده می کنیم

 

      <asp:TemplateField HeaderText="دستورات">
                    <ItemTemplate>
                        <asp:LinkButton ID="LinkButton1" runat="server" CommandArgument='<%# Eval("UserID") %>' Visible='<%#(bool)CheckPermission.Check(4) %>'>تعیین دسترسی</asp:LinkButton>
                        <br />
                    </ItemTemplate>
                </asp:TemplateField>

 

فایل های ضمیمه

ایمان مدائنی

نویسنده 1299 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید