1

I've decided to use forms authentication to log in users, unfortunetly i have some problems with that. I would like if user log in correctly to move him to some specific controller and from that point he could go over other controllers with check if he's really authorized. Of course in all controller's methods there will be check if user was really authenticated right? This is main question and 3 other questions at the bottom of this topic. Please of your support.

So far i have this code in my LoginController:

    Function Index() As ActionResult
        Return View()
    End Function

    'Action for POST method (login)
    <HttpPost>
    <AllowAnonymous>
    Function Index(ByVal user As tbLogin) As ActionResult
        Try
            If (ModelState.IsValid) Then
                If IsValid(user.Login, user.Password) Then
                    FormsAuthentication.SetAuthCookie(user.Id, False)
                    Return RedirectToAction("AfterLogin")
                Else
                    ViewData("Success") = "Login error"
                End If
            End If
        Catch ex As Exception
            Return RedirectToAction("Index", "Home")
        End Try
        Return View(user)

    End Function

  'Action for Show view after login
    <Authorize>
    Function AfterLogin() As ActionResult
            Return RedirectToAction("Index", "Home")
        End If
    End Function

 Function IsValid(Login As String, password As String) As Boolean
        Dim _isValid As Boolean = False

        Using dc = New woitgroup_transport.production_WojtgroupEntitesContext
            Dim user = dc.tbLogin.Where(Function(a) a.Login.Equals(Login) And a.Password.Equals(password)).FirstOrDefault()

            If Not IsNothing(user) Then
                If user.Password = password Then
                    _isValid = True
                End If
            End If

        End Using
        Return _isValid
    End Function

In webconfig:

<authentication mode="Forms">
  <forms loginUrl="~/Login/Index" timeout="2880" />
</authentication>

1st question: Currently in every controller and every method i marked them as <Authorized> . I checked typing manually links to address and without user login user will be redirected to login page (because of webconfig) - seems it's working. Can you confirm this way?

e.g:

<Authorize>
    Public Function Index(model As CustomModelProjetsTransports, Optional filter As String = "") As ActionResult

3rd question: Since i kept user.Id here: FormsAuthentication.SetAuthCookie(user.Id, False) i would like to read this id in some controller. How can i read this value?

4th question: is there any timeout for since user authnticated?

5th question: Is this command correct to log out user - to break session?: FormsAuthentication.SignOut

FOR FURTHER DISCUSSIONS (with @C0dingJammer)- EXTENDED:

 <HttpPost>
    <AllowAnonymous>
    <ValidateAntiForgeryToken>
    Function Index(ByVal user As tbLogin) As ActionResult
        Try
            If (ModelState.IsValid) Then
                Dim userId As Integer
                If Not IsNothing(GetUserIdIfValid(user.Login, user.Password)) Then
                    userId = GetUserIdIfValid(user.Login, user.Password)
                    'false wywali cookie po zamknieciu browser - true zostawi
                    FormsAuthentication.SetAuthCookie(userId, False)
                    Return RedirectToAction("AfterLogin")
                Else
                    ViewData("Success") = "Login error"
                End If
            End If
        Catch ex As Exception
            Return RedirectToAction("Index", "Home")
        End Try
        Return View(user)

    End Function

This should only return false/true but to get also user.Id i refactored it to get this is and pass to FormsAuthentication.SetAuthCookie(userId, False). I am looking for to make it bit better than it is right now:

Function GetUserIdIfValid(Login As String, password As String) As Object
        Dim _getuserId As Object = Nothing
        Using dc = New woitgroup_transport.production_WojtgroupEntitesContext
            Dim user = dc.tbLogin.Where(Function(a) a.Login.Equals(Login) And a.Password.Equals(password)).FirstOrDefault()

            If Not IsNothing(user) Then
                If user.Password = password Then
                    _getuserId = user.Id
                End If
            End If
        End Using
        Return _getuserId
    End Function

1 Answers1

2

2 Question: Yes you can set the login form in the web.config See Question 4

3th Question: How to get current user in Asp.Net MVC

If you need to get the user from within the controller, use the User property of Controller. If you need it from the view, I would populate what you specifically need in the ViewData, or you could just call User as I think it's a property of ViewPage.

4th Question. You can set the timeout of the loged in user in the Web.config file. Mine looks like this:

 <system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="1440" /> <!--1440Min = 24Hours-->
    </authentication>
.....
 </system.web>

When the Login-time expires the user gets logged off (Does'nt update GUI automatically). If he clicks now on the link wich redirects him to the 'EmployeeController' which has set the Attribute '[Authorize]' he gets redirected to the Login-Page which has been set in the web.config file. If the EmployeeController wouldnt had the Attribute it would allow the user to access the (controller) site/view as a normal user

 [Authorize]
 public class EmployeeController : Controller
 {
       private ActionResult Index()
        {
            return View("You are allowed to see this page, because you are logged-in");
        }
 }

So only auth. user are allowed to acccess Employes-Controlelr. If they dont have permission they are getting redirected to login page

5th Question Yes its correct but you need to redirect to the view instead of just passing the view.

    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();

        //Important part
        return RedirectToAction("Index", "ErrorLogs");
    }

I hope it helps.

EDIT (Discussion)

//This is the model which is used as a object to transfer data from View to Controller. Itself contains a method named Validate which is validating the user against Ad for ex.
public class tbLogin
{
    public string UserId { get; set;}
    private string Password { get; set;}

    public tbLogin(string uId, string pw)
    {
        this.UserId = uId;
        this.Password = pw;
    }

    public boolean Validate()
    {
        if(String.IsNullOrEmpty(UserId) || String.IsNullOrEmpty(Password)) { return; }
        //Validate user against Active Directory for ex.    
        return true;
    }
}


//This is your method in your account controller. It gets the data from the view and calls the validation method in the model
//Post
Public ActionResult Index(tbLogin user)
{

    if (!ModelState.IsValid)
    {
        return View(user);
    }

    if(user == null) 
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    try
    {
        if(user.Validate())
        {
            FormsAuthentication.SetAuthCookie(user.UserId, False);
            return RedirectToAction("AfterLogin");
        }
        else
        {
            //ViewData("Success") = "Login error"
        }
    }
    catch(Exception ex)
    {
         //Handle Expetion and redirect to Home-index
         return  RedirectToAction("Index","Home");
    }

    return View(user);
}
Community
  • 1
  • 1
C0d1ngJammer
  • 550
  • 1
  • 6
  • 21
  • hi still have some confusion. I set timeout to "5" and after that time i was able to use program - there was no redirection to Login page. Second thing i don;t get how to make it work - as you see i am getting user.Id to my cookie: FormsAuthentication.SetAuthCookie(user.Id, False) . Now being in another controller how to access this value - Can you show as an asnwer? –  Dec 22 '15 at 11:25
  • Check my updated answer out. Makes shure u have set Attribut of the controller the user is directing to set to [Authorize] – C0d1ngJammer Dec 22 '15 at 11:58
  • You just have to call 'User.Identity.GetUserName()' in the controller – C0d1ngJammer Dec 22 '15 at 12:00
  • Everywhere i have this attribute :). User.Identity.GetUserName() - there is no method like this (GetUserName)... how to access User.Id ? –  Dec 22 '15 at 12:10
  • Try to import namespace Microsoft.AspNet.Identity. Its an extension. – C0d1ngJammer Dec 22 '15 at 12:20
  • 1
    Between your User.Id is 'User.Identity.GetUserName()'. Normally you set the username and not the ID when using this method [FormsAuthentication.SetAuthCookie(username, False)](https://msdn.microsoft.com/de-de/library/twk5762b%28v=vs.110%29.aspx) – C0d1ngJammer Dec 22 '15 at 12:25
  • User.Id is comming from my table user and that what i want to be able to access in every controller. P.S I can't find this Microsoft.AspNet.Identity (i am using net 4 and mvc 4 maybe thats problem? –  Dec 22 '15 at 12:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/98695/discussion-between-manuchao-and-johndoe). – C0d1ngJammer Dec 22 '15 at 12:42
  • Many thanks to C0dingJammer for all his engagement over this topic - finally (based on his input). @C0dingJammer - one more thing - when i am doing FormsAuthentication.SetAuthCookie(user.Id, False) then i could access my User.Id by System.Web.HttpContext.Current.User.Identity.Name , what if i would like to like to store more values besides User.Id , e.g User.Login ? That's my last question. –  Dec 24 '15 at 11:02
  • Well one way would be to override the class of the .net Authentication. Or just create your own Model representing the User. With Proerties such as Name, City, street.... you just have to make shure its somehow linked with the User.Id and your User class. In my case Iam creating for each user who loggs in (Controller-Login) a User class wich is linked with the User.ID of the formsauth. – C0d1ngJammer Dec 28 '15 at 07:37
  • In this case your tbLogin (which I would just call 'User') holds more Proerties like street, city, loginTime..... In you Login method in your (Account) Controller u would have to link it with the id of the formsauth. – C0d1ngJammer Dec 28 '15 at 07:53