تعیین سطح دسترسی کاربران (بصورت جزئی به اجزا سایت) در Asp.Net
یکشنبه 24 خرداد 1394در این مقاله قصد داریم تعیین سطح دسترسی هر کار بر صورت جداگانه به عناصر صفحات و خود صفحات را به صورت داینامیک و در لحظه اجرا یاد بدیم .

ابتدا باید جداول مورد نظر را بسازیم
یک بانک اطلاعاتی با نام 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>
- ASP.net
- 10k بازدید
- 22 تشکر