تخصیص نقش ها به کاربران بر اساس احراز هویت در Asp.Net

دوشنبه 11 اسفند 1393

در این مقاله نحوه تخصیص نقش ها به کاربران در هنگام اجرای نرم افزار فرم ها در Asp.Net با استفاده از #C و VB.NET شرح داده خواهد شد

تخصیص نقش ها  به کاربران بر اساس احراز هویت در Asp.Net

ابتدا در بانک اطلاعاتی جدولی مانند زیر تولید می کنیم :

Users

Roles

جدول نقش ها دارای دو نقش میباشد که شامل Administrator و User می باشد

سپس در ویژوال استودیو در صفحه مزبوطه یک کنترل Login که با رویداد اختصاص یافته است قرار می دهیم مانند کد زیر :


<asp:Login ID = "Login1" runat = "server" OnAuthenticate= "ValidateUser"></asp:Login>

 

شما باید NameSpace های زیر را به صفحه مورد نظر اضافه کنید :

برای کد C# :


using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Security;

و برای کد VB.NET :


Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Web.Security

روش های ذخیره اعتبار کاربر و گرفتن نقش آن :

1 : روش ذخیره اعتبار کاربر و اختصاص دادن نقش به کاربر می باشد که آیا نام کاربر تکراری می باشد یا رمز عبور درست است در غیر اینصورت 1- را بر می گرداند

2 : اگر نام کاربری و رمز عبور صحیح بود ولی کاربر توسط مدیر فعال نشده بود سپس کد 2- را بر می گرداند

3 : اگر نام کاربری و رمز عبور صحیح بود و کاربر توسط مدیر فعال شده بود سپس UserID و Role را در کد بر می گرداند.


CREATE PROCEDURE [dbo].[Validate_User]
      @Username NVARCHAR(20),
      @Password NVARCHAR(20)
AS
BEGIN
      SET NOCOUNT ON;
      DECLARE @UserId INT, @LastLoginDate DATETIME, @RoleId INT
     
      SELECT @UserId = UserId, @LastLoginDate = LastLoginDate, @RoleId = RoleId
      FROM Users WHERE Username = @Username AND [Password] = @Password
     
      IF @UserId IS NOT NULL
      BEGIN
            IF NOT EXISTS(SELECT UserId FROM UserActivation WHERE UserId = @UserId)
            BEGIN
                  UPDATE Users
                  SET LastLoginDate = GETDATE()
                  WHERE UserId = @UserId
                 
                  SELECT @UserId [UserId],
                              (SELECT RoleName FROM Roles
                               WHERE RoleId = @RoleId) [Roles] -- User Valid
            END
            ELSE
            BEGIN
                  SELECT -2 [UserId], '' [Roles]-- User not activated.
            END
      END
      ELSE
      BEGIN
            SELECT -1 [UserId], '' [Roles] -- User invalid.
      END
END

 

اعتبارسنجی کاربر و تعیین نقش آن :

رویداد زیر زمانی فرا خوانی می شود که دکمه Log In کلیک شود.در اینجا UserName و Password اعتبار سنجی میشود و در صورت مجاز بودن کاربر نقش کاربر را بر می گرداند.

Role و UserId گرفته شده توسط  FormsAuthenticate چک میشود و در صورت صحت اطلاعات ورودی کاربر را به صفحه اصلی که در Web.config تعریف کرده ایم هدایت می کند.

کد C# :


protected void ValidateUser(object sender, EventArgs e)
{
    int userId = 0;
    string roles = string.Empty;
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("Validate_User"))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Username", Login1.UserName);
            cmd.Parameters.AddWithValue("@Password", Login1.Password);
            cmd.Connection = con;
            con.Open();
            SqlDataReader reader = cmd.ExecuteReader();
            reader.Read();
            userId = Convert.ToInt32(reader["UserId"]);
            roles = reader["Roles"].ToString();
            con.Close();
        }
        switch (userId)
        {
            case -1:
                Login1.FailureText = "Username and/or password is incorrect.";
                break;
            case -2:
                Login1.FailureText = "Account has not been activated.";
                break;
            default:
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), Login1.RememberMeSet, roles, FormsAuthentication.FormsCookiePath);
                string hash = FormsAuthentication.Encrypt(ticket);
                HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
 
                if (ticket.IsPersistent)
                {
                    cookie.Expires = ticket.Expiration;
                }
                Response.Cookies.Add(cookie);
                Response.Redirect(FormsAuthentication.GetRedirectUrl(Login1.UserName, Login1.RememberMeSet));
                break;
        }
    }
}

کد VB.NET :


Protected Sub ValidateUser(sender As Object, e As EventArgs)
    Dim userId As Integer = 0
    Dim roles As String = String.Empty
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As New SqlConnection(constr)
        Using cmd As New SqlCommand("Validate_User")
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.AddWithValue("@Username", Login1.UserName)
            cmd.Parameters.AddWithValue("@Password", Login1.Password)
            cmd.Connection = con
            con.Open()
            Dim reader As SqlDataReader = cmd.ExecuteReader()
            reader.Read()
            userId = Convert.ToInt32(reader("UserId"))
            roles = reader("Roles").ToString()
            con.Close()
        End Using
        Select Case userId
            Case -1
                Login1.FailureText = "Username and/or password is incorrect."
                Exit Select
            Case -2
                Login1.FailureText = "Account has not been activated."
                Exit Select
            Case Else
                Dim ticket As New FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), Login1.RememberMeSet, roles, _
                 FormsAuthentication.FormsCookiePath)
                Dim hash As String = FormsAuthentication.Encrypt(ticket)
                Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, hash)
 
                If ticket.IsPersistent Then
                    cookie.Expires = ticket.Expiration
                End If
                Response.Cookies.Add(cookie)
                Response.Redirect(FormsAuthentication.GetRedirectUrl(Login1.UserName, Login1.RememberMeSet))
                Exit Select
        End Select
    End Using
End Sub

در کنار رویداد Application_AuthenticateRequest فایل Global.asax  نقش ها از FormsAuthentication Ticket بازخوانی می شوند و به HttpContext User object متصل میشوند.

به این ترتیب کاربر در سراسر برنامه از طریق Context قابل دسترس است.

کد مخصوص C# :


protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    if (HttpContext.Current.User != null)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated)
        {
            if (HttpContext.Current.User.Identity is FormsIdentity)
            {
                FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
                FormsAuthenticationTicket ticket = id.Ticket;
                string userData = ticket.UserData;
                string[] roles = userData.Split(',');
                HttpContext.Current.User = new GenericPrincipal(id, roles);
            }
        }
    }
}
کد VB.NET :

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
    If HttpContext.Current.User IsNot Nothing Then
        If HttpContext.Current.User.Identity.IsAuthenticated Then
            If TypeOf HttpContext.Current.User.Identity Is FormsIdentity Then
                Dim id As FormsIdentity = DirectCast(HttpContext.Current.User.Identity, FormsIdentity)
                Dim ticket As FormsAuthenticationTicket = id.Ticket
                Dim userData As String = ticket.UserData
                Dim roles As String() = userData.Split(","c)
                HttpContext.Current.User = New GenericPrincipal(id, roles)
            End If
        End If
    End If
End Sub

تکمیل کنترل GridView همراه با نقش کاربران :

تگ های HTML شامل کنترل GridView مخصوص به Asp.Net با یک ستون BoundField برای نمایش نام کاربری و دو TemplateField که در یکیDropDownList و دیگری شامل دکمه میباشد.کنترل GridView که به یک رویداد OnRowDataBound  متصل شده است.


<asp:Panel ID="pnlAssignRoles" runat="server" Visible="false">
    <asp:GridView ID="gvUsers" runat="server" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound">
        <Columns>
            <asp:BoundField DataField="Username" HeaderText="Username" />
            <asp:TemplateField HeaderText="Role">
                <ItemTemplate>
                    <asp:DropDownList ID="ddlRoles" runat="server">
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Role">
                <ItemTemplate>
                    <asp:Button ID="btnUpdate" Text="Update" runat="server" CommandArgument='<%# Eval("UserId") %>'
                        OnClick="UpdateRole" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</asp:Panel>

یکبار کاربر وارد سایت می شود , چک میشود که کاربر وارد شده چه نقشی دارد , اگر کاربر وارد شده نقش مدیر را دارد سپس کنترل GridView قابل نمایش میباشد , داخل رویداد OnRowDataBound کنترل DropDownList  که هر سطر نقش کاربران را از جدول Rols  فراخوانی می کند و نمایش میدهد.یکبار DropDownList  نمایش داده میشود و نقش مربوط به هر سطر را به کاربر مربوط به آن سطر نمایش می دهد.

کد C# :


protected void Page_Load(object sender, EventArgs e)
{
    if (!this.IsPostBack)
    {
        if (!this.Page.User.Identity.IsAuthenticated)
        {
            Response.Redirect("~/Login.aspx");
        }
        if (this.Page.User.IsInRole("Administrator"))
        {
            pnlAssignRoles.Visible = true;
            gvUsers.DataSource = GetData("SELECT UserId, Username, RoleId FROM Users");
            gvUsers.DataBind();
        }
    }
}
 
private DataTable GetData(string query)
{
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand(query))
        {
            cmd.CommandType = CommandType.Text;
            cmd.Connection = con;
            using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
            {
                DataTable dt = new DataTable();
                sda.Fill(dt);
                return dt;
            }
        }
    }
}
 
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DropDownList ddlRoles = (e.Row.FindControl("ddlRoles") as DropDownList);
        ddlRoles.DataSource = GetData("SELECT RoleId, RoleName FROM Roles");
        ddlRoles.DataTextField = "RoleName";
        ddlRoles.DataValueField = "RoleId";
        ddlRoles.DataBind();
 
        string assignedRole = (e.Row.DataItem as DataRowView)["RoleId"].ToString();
        ddlRoles.Items.FindByValue(assignedRole).Selected = true;
    }
}

 

کد VB.NET :


Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not Me.IsPostBack Then
        If Not Me.Page.User.Identity.IsAuthenticated Then
            Response.Redirect("~/Login.aspx")
        End If
        If Me.Page.User.IsInRole("Administrator") Then
            pnlAssignRoles.Visible = True
            gvUsers.DataSource = GetData("SELECT UserId, Username, RoleId FROM Users")
            gvUsers.DataBind()
        End If
    End If
End Sub
 
Private Function GetData(query As String) As DataTable
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As New SqlConnection(constr)
        Using cmd As New SqlCommand(query)
            cmd.CommandType = CommandType.Text
            cmd.Connection = con
            Using sda As New SqlDataAdapter(cmd)
                Dim dt As New DataTable()
                sda.Fill(dt)
                Return dt
            End Using
        End Using
    End Using
End Function
 
Protected Sub OnRowDataBound(sender As Object, e As GridViewRowEventArgs)
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim ddlRoles As DropDownList = TryCast(e.Row.FindControl("ddlRoles"), DropDownList)
        ddlRoles.DataSource = GetData("SELECT RoleId, RoleName FROM Roles")
        ddlRoles.DataTextField = "RoleName"
        ddlRoles.DataValueField = "RoleId"
        ddlRoles.DataBind()
 
        Dim assignedRole As String = TryCast(e.Row.DataItem, DataRowView)("RoleId").ToString()
        ddlRoles.Items.FindByValue(assignedRole).Selected = True
    End If
End Sub

نحوه ارتباط نقش ها به کاربران :

هنگامی دکمه Update کلیک میشود , UserId از سطر مورد نظر با استفاده از خاصیت CommandArgument فرا خوانی می شود و RoleId  نیز از DropDownList خوانده میشود . و در آخر نقش هر کاربر از جدول Rols خوانده و ویرایش میشود
 .

کد #C :


protected void UpdateRole(object sender, EventArgs e)
{
    GridViewRow row = ((sender as Button).NamingContainer as GridViewRow);
    int userId = int.Parse((sender as Button).CommandArgument);
    int roleId = int.Parse((row.FindControl("ddlRoles") as DropDownList).SelectedItem.Value);
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("UPDATE Users SET RoleId = @RoleId WHERE UserId = @UserId"))
        {
            cmd.Parameters.AddWithValue("@UserId", userId);
            cmd.Parameters.AddWithValue("@RoleId", roleId);
            cmd.CommandType = CommandType.Text;
            cmd.Connection = con;
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }
}

کد VB.NET :


Protected Sub UpdateRole(sender As Object, e As EventArgs)
    Dim row As GridViewRow = TryCast(TryCast(sender, Button).NamingContainer, GridViewRow)
    Dim userId As Integer = Integer.Parse(TryCast(sender, Button).CommandArgument)
    Dim roleId As Integer = Integer.Parse(TryCast(row.FindControl("ddlRoles"), DropDownList).SelectedItem.Value)
    Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As New SqlConnection(constr)
        Using cmd As New SqlCommand("UPDATE Users SET RoleId = @RoleId WHERE UserId = @UserId")
            cmd.Parameters.AddWithValue("@UserId", userId)
            cmd.Parameters.AddWithValue("@RoleId", roleId)
            cmd.CommandType = CommandType.Text
            cmd.Connection = con
            con.Open()
            cmd.ExecuteNonQuery()
            con.Close()
        End Using
    End Using
End Sub

ویرایش نقش ها و نمایش آنها در جدول

 

 

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

برنامه نویسان

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

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

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