locked
Redirection based on role RRS feed

  • Question

  • User-1767698477 posted

    I'm using Forms authentication and I have a need to be able to redirect to 2 different pages.  At the moment, I have a Siteuser database which stores the main username and password but the user will have an assistant who will have a different (smaller) profile of information. I put the assistant's username and password on the same row as the main user. only the main user will pay for the service, and the assistant's login is free. Is storing them both on the same row a security issue? If so, why would it be? I'm using a sql query that checks the textbox input for the main username and password against the values in the row for both the main user and the assistant.  This is working but the problem is that when the assistant logs out, there is a long return url left in the url window.  If the main user enters his credentials, that will pull up the page of the assistant! I was trying to do a check for this by setting a flag in the login page:

    Protected Function Authentication(ByVal username As String, ByVal password As String) As [Boolean]

    If reader("Processoruser") IsNot DBNull.Value Then
    Session("Processoruser") = reader("Processoruser").ToString()
    End If

    If username = Session("Processoruser") Then
    'set flag for processor login
    Session("Processorlogin") = "Y"
    Else : Session("Processorlogin") = "N"

    Then in my page load of the users/default.aspx, I run this:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Session("Processorlogin") = "Y" Then
    Response.Redirect("processor_profile.aspx")
    End If
    If Not IsPostBack Then
    If Session("Processorlogin") = "Y" Then
    Response.Redirect("processor_profile.aspx")
    End If

    This only works when logging in with the processor credentials. But after logout, a long url is left in the window of the previous page the processor was just on.  Is there a way to make asp.net not put this returnurl every time upon logout? This was the last page you visited, and for convenience asp.net likes to put this in the url window. Why does it do this?  Why can't it just take the user to a nice clean loginurl.aspx url every time? no appended ?...

    I'm thinking that I need to do forms redirection based on roles. I have read about this. I have an admin and user role. But there are really two types of users and two different profiles. So I'm thinking that at registration time, they should select their role from a drop down, and then complete a registration profile based on the role.

    So presently users/default.aspx is the forms login redirect page. How do I tell it to redirect for a certain role, and redirect to a different page for another role? The users should not be able to view the other's page.

    Sunday, April 26, 2020 12:02 AM

Answers

  • User-1330468790 posted

    Hi sking,

      

    But after logout, a long url is left in the window of the previous page the processor was just on.  Is there a way to make asp.net not put this returnurl every time upon logout?

    Could you please share the code about the logout method?

    The FormsAuthentication.SignOut will only remove the forms authentication cookie and should not leave any return URL.

    Normally, the SignOut method works with the RedirectToLoginPage to log out an user and allow another one to log in.

      

    I'm thinking that I need to do forms redirection based on roles. I have read about this. I have an admin and user role. But there are really two types of users and two different profiles. So I'm thinking that at registration time, they should select their role from a drop down, and then complete a registration profile based on the role.

    I think this is a question about the role design. You could either design the role selection at registration time or make an registered user with an default role and let them choose to be an main user and add an default user as his assistant.

      

    So presently users/default.aspx is the forms login redirect page. How do I tell it to redirect for a certain role, and redirect to a different page for another role? The users should not be able to view the other's page.

    I suggest you use Role-Based Authorization which is a part of the form authentication.

    Then you could use code like below (Just for reference): to Redirect to different page.

    Try
    
        If Membership.ValidateUser(Login1.UserName, Login1.Password)
        Then
            If Roles.IsUserInRole(Login1.UserName, "main")
            Then
                Response.Redirect("~/main/Default.aspx")
            ElseIf Roles.IsUserInRole(Login1.UserName, "assistant")
            Then
                Response.Redirect("~/assistant/Default.aspx")
            End If
        End If
    Catch ex As Exception
    
    End Try

     

    The access for different page could be set in the web.config file.

    For example,

    <location path="master.aspx">
              <system.web>
                   <authorization>
                       <allow roles="master" />
                       <deny users="*" />
                   </authorization>
              </system.web>
         </location>
    <location path="assistant.aspx">
              <system.web>
                   <authorization>
                       <allow roles="assistant" />
                       <deny users="*" />
                   </authorization>
              </system.web>
         </location>
    
    

    Also, you could write your own Role provide to implement your own logic (web.config).

    <roleManager defaultProvider="CustomRoleProvider" >
             <providers>
               <clear />
               <add name="CustomRoleProvider" type="YourNameSpace.CustomRoleProvider" />
             </providers>
           </roleManager>
        </system.web>

      

    Hope this can help you.

    Best regards,

    Sean

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, April 27, 2020 3:27 AM

All replies

  • User-1330468790 posted

    Hi sking,

      

    But after logout, a long url is left in the window of the previous page the processor was just on.  Is there a way to make asp.net not put this returnurl every time upon logout?

    Could you please share the code about the logout method?

    The FormsAuthentication.SignOut will only remove the forms authentication cookie and should not leave any return URL.

    Normally, the SignOut method works with the RedirectToLoginPage to log out an user and allow another one to log in.

      

    I'm thinking that I need to do forms redirection based on roles. I have read about this. I have an admin and user role. But there are really two types of users and two different profiles. So I'm thinking that at registration time, they should select their role from a drop down, and then complete a registration profile based on the role.

    I think this is a question about the role design. You could either design the role selection at registration time or make an registered user with an default role and let them choose to be an main user and add an default user as his assistant.

      

    So presently users/default.aspx is the forms login redirect page. How do I tell it to redirect for a certain role, and redirect to a different page for another role? The users should not be able to view the other's page.

    I suggest you use Role-Based Authorization which is a part of the form authentication.

    Then you could use code like below (Just for reference): to Redirect to different page.

    Try
    
        If Membership.ValidateUser(Login1.UserName, Login1.Password)
        Then
            If Roles.IsUserInRole(Login1.UserName, "main")
            Then
                Response.Redirect("~/main/Default.aspx")
            ElseIf Roles.IsUserInRole(Login1.UserName, "assistant")
            Then
                Response.Redirect("~/assistant/Default.aspx")
            End If
        End If
    Catch ex As Exception
    
    End Try

     

    The access for different page could be set in the web.config file.

    For example,

    <location path="master.aspx">
              <system.web>
                   <authorization>
                       <allow roles="master" />
                       <deny users="*" />
                   </authorization>
              </system.web>
         </location>
    <location path="assistant.aspx">
              <system.web>
                   <authorization>
                       <allow roles="assistant" />
                       <deny users="*" />
                   </authorization>
              </system.web>
         </location>
    
    

    Also, you could write your own Role provide to implement your own logic (web.config).

    <roleManager defaultProvider="CustomRoleProvider" >
             <providers>
               <clear />
               <add name="CustomRoleProvider" type="YourNameSpace.CustomRoleProvider" />
             </providers>
           </roleManager>
        </system.web>

      

    Hope this can help you.

    Best regards,

    Sean

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, April 27, 2020 3:27 AM
  • User-1767698477 posted

    Hi Sean,

    I have been very busy. Thanks for your help on this issue with roles . There are columns in my Siteuser table for username, password and roles. I have the following code behind on my login.aspx page. I tried logging in with users with the role of user or processor. They always go to the /users directory regardless of what is in the roles column. I need to get users with a processor role to go to /users2. As you can see, I commented out the line FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet)

    Imports System.Data
    Imports System.Data.SqlClient
    Partial Class login
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load

    If Not IsPostBack Then
    If ((Not (Request.Cookies("UserName")) Is Nothing) _
    AndAlso (Not (Request.Cookies("Password")) Is Nothing)) Then
    Login1.UserName = Request.Cookies("UserName").Value
    Login1.Attributes("value") = Request.Cookies("Password").Value
    End If
    End If
    End Sub

    Protected Sub Login1_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) Handles Login1.Authenticate
    Dim authenticated As Boolean
    If Login1.RememberMeSet Then
    Response.Cookies("UserName").Expires = DateTime.Now.AddDays(30)
    Response.Cookies("Password").Expires = DateTime.Now.AddDays(30)
    Else
    Response.Cookies("UserName").Expires = DateTime.Now.AddDays(-1)
    Response.Cookies("Password").Expires = DateTime.Now.AddDays(-1)
    End If
    Response.Cookies("UserName").Value = Login1.UserName.Trim
    Response.Cookies("Password").Value = Login1.Password.Trim

    authenticated = Authentication(Login1.UserName, Login1.Password)
    If authenticated Then
    'Dim UserName As String = Login1.UserName
    If Roles.IsUserInRole(Login1.UserName, "user") Then
    Response.Redirect("~/users/Default.aspx")
    ElseIf Roles.IsUserInRole(Login1.UserName, "processor") Then
    Response.Redirect("~/users2/Default.aspx")
    End If
    'FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet)
    End If
    Session("Check") = authenticated
    e.Authenticated = authenticated
    End Sub
    Protected Function Authentication(ByVal username As String, ByVal password As String) As [Boolean]
    Dim correct As Boolean = False
    Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("sqlConnectionString").ConnectionString)
    Using command As New SqlCommand("GetUserLoginDetails", con)
    command.Parameters.Add(New SqlParameter("@Username", SqlDbType.VarChar)).Value = username
    command.Parameters.Add(New SqlParameter("@Password", SqlDbType.VarChar)).Value = password
    command.Parameters.Add(New SqlParameter("@ProcessorUser", SqlDbType.VarChar)).Value = username
    command.Parameters.Add(New SqlParameter("@ProcessorPw", SqlDbType.VarChar)).Value = password
    command.CommandType = CommandType.StoredProcedure
    con.Open()
    If con.State = ConnectionState.Open Then
    Using reader As SqlDataReader = command.ExecuteReader()
    If reader.Read() Then
    If reader("Firstname") IsNot DBNull.Value Then
    Session("firstname") = reader("firstname").ToString()
    End If
    If reader("Lastname") IsNot DBNull.Value Then
    Session("lastname") = reader("lastname").ToString()
    End If
    If reader("Username") IsNot DBNull.Value Then
    Session("Username") = reader("Username").ToString()
    End If
    If reader("Phone") IsNot DBNull.Value Then
    Session("Phone") = reader("Phone").ToString()
    End If
    If reader("Email") IsNot DBNull.Value Then
    Session("Email") = reader("Email").ToString()
    End If
    If reader("Password") IsNot DBNull.Value Then
    Session("Password") = reader("Password").ToString()
    End If
    If reader("UserID") IsNot DBNull.Value Then
    Session("UserID") = reader("UserID").ToString()
    End If
    If reader("roles") IsNot DBNull.Value Then
    Session("roles") = reader("roles").ToString()
    End If
    If reader("UnlockCode") IsNot DBNull.Value Then
    Session("path") = reader("UnlockCode").ToString()
    End If
    If reader("ProcessorFirst") IsNot DBNull.Value Then
    Session("ProcessorFirst") = reader("ProcessorFirst").ToString()
    End If
    If reader("ProcessorLast") IsNot DBNull.Value Then
    Session("ProcessorLast") = reader("ProcessorLast").ToString()
    End If
    If reader("Processoruser") IsNot DBNull.Value Then
    Session("Processoruser") = reader("Processoruser").ToString()
    End If
    If reader("Processorpw") IsNot DBNull.Value Then
    Session("Processorpw") = reader("Processorpw").ToString()
    End If
    If reader("Processoremail") IsNot DBNull.Value Then
    Session("Processoremail") = reader("Processoremail").ToString()
    End If
    If reader("Processorinfo") IsNot DBNull.Value Then
    Session("Processorinfo") = reader("Processorinfo").ToString()
    End If
    If reader("Processordob") IsNot DBNull.Value Then
    Session("Processordob") = reader("Processordob").ToString()
    End If

    If username = Session("Processoruser") Then
    'set flag for processor login
    Session("Processorlogin") = "Y"
    Else : Session("Processorlogin") = "N"
    End If
    correct = True
    End If
    End Using
    Else
    End If
    End Using
    End Using
    Return correct
    End Function
    End Class

    I regards to roles, is it possible to have more than one role column on the same row in the table? I have the main user and password and the assistant username and password on the same row in the table. They both need separate roles to be taken to the correct folder upon login.

    Also you asked me about:

    Could you please share the code about the logout method?

    The FormsAuthentication.SignOut will only remove the forms authentication cookie and should not leave any return URL.

    Normally, the SignOut method works with the RedirectToLoginPage to log out an user and allow another one to log in.

    On the master page for the pages in /users, at the top I have:

    asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server">
    <form id="Form1" runat="server">
    <br />
    <table align="center" width="95%">
    <tr>
    <td align="left">
    Welcome : <b>
    <asp:Label ID="lblName" runat="server" Text="" ForeColor="#FFB30F"></asp:Label></b>
    </td>
    <td>
    </td>
    <td align="right">
    <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="changepassword.aspx">Change Password</asp:HyperLink>
    </td>
    </tr>
    <tr>
    <td align="left">
    <asp:LoginView ID="LoginView1" runat="server">
    <LoggedInTemplate>
    Logged in as :
    <asp:LoginName ID="LoginName1" runat="server" Font-Bold="True" />
    </LoggedInTemplate>
    <AnonymousTemplate>
    Your are not logged in.
    <br />
    Click the login link to sign in.
    </AnonymousTemplate>
    </asp:LoginView>
    </td>
    <td>
    </td>
    <td align="right">
    <asp:HyperLink ID="HyperLink4" runat="server" NavigateUrl="edit_profile.aspx">Edit Profile</asp:HyperLink>
    </td>
    </tr>
    <tr>
    <td align="left">
    <asp:LoginStatus ID="LoginStatus1" runat="server" />
    </td>

    So when you are logged in, the loginstatus shows a Logout link. When you click the link, you are taken to the login.aspx page but there is a long url in the browser.

    Thursday, April 30, 2020 5:05 AM
  • User-1767698477 posted

    From this article  https://docs.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication.signout?view=netframework-4.8

    I put this in my page and it leaves a long url in my browser just the same way it does with the login status control.

    <asp:LoginView ID="LoginView1" runat="server">
    <LoggedInTemplate>
    Logged in as :
    <asp:LoginName ID="LoginName1" runat="server" Font-Bold="True" />
    </LoggedInTemplate>
    <AnonymousTemplate>
    Your are not logged in.
    <br />
    Click the login link to sign in.
    </AnonymousTemplate>
    </asp:LoginView>
    </td>
    <td>
    </td>
    <td align="right">
    <asp:HyperLink ID="HyperLink4" runat="server" NavigateUrl="edit_profile.aspx">Edit Profile</asp:HyperLink>
    </td>
    </tr>
    <tr>
    <td align="left">
    <asp:LinkButton id="LoginLink" Text="here"
    OnClick="LoginLink_OnClick" runat="server" />
    <asp:LoginStatus ID="LoginStatus1" runat="server" />

    Public Sub LoginLink_OnClick(ByVal sender As Object, ByVal args As EventArgs)
    FormsAuthentication.SignOut()
    FormsAuthentication.RedirectToLoginPage()
    End Sub

    I click here "here" or "Logout" and this is what is in my browser bar

    http://localhost:53925/mortgageloanapply/login.aspx?ReturnUrl=%2fmortgageloanapply%2fusers%2fdefault.aspx

    http://localhost:53925/mortgageloanapply/login.aspx?ReturnUrl=%2fmortgageloanapply%2fusers%2fdefault.aspx

    Friday, May 1, 2020 5:06 AM