locked
User Authentication and Session Variables RRS feed

  • Question

  • User-596903714 posted

    Is it possible to force a user to re-logon if the value of session variable is blank and, can that functionality be coded in 1 place within MVC?

    If not, is it possible/what is the best way to easily access information associated with the user after they have logged on without repeatedly querying the user SQL table?  I looked at using Claims but, I am confused by their usage and can't seem to store a Custom Claim name and value.  E.G. I want to store a Claim name called CustomerID with the Value of ABC123, but, based on examples I can find, I can only store the claim name and not an actual value for it (as shown in this link).

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-create-a-custom-claim

    Claim c1 = new Claim ( "http://example.org/claims/simplecustomclaim", "Driver's License", Rights.PossessProperty);

    This code seems to indicate the user HAS a driver's License, but does not give the functionality to store the Drivers License ID.

    My scenario is, the users data can be stored in different databased depending on the company they work for and/or country.  I have a single database that contains all the user logon's for my site and the database name the customers data resides in.  When the user logins in, the database name is also queried and stored in a session variable for easy use within the site and various queries.  If the web server is restarted or the session information is reset, the user remains logged in but their Database name becomes blank and all pages start to error out.  

    I thought about adding code to lookup the user ID on the session start command and restore the database name.  That might work but I am also using session variables for other settings that the user can customize so, I need the user to be aware that they are having to log back in.

    Any ideas?

    Tuesday, July 11, 2017 7:31 PM

All replies

  • User-596903714 posted

    Is it possible to force a user to re-logon if the value of session variable is blank and, can that functionality be coded in 1 place within MVC?


    If not, is it possible/what is the best way to easily access information associated with the user after they have logged on without repeatedly querying the user SQL table?  I looked at using Claims but, I am confused by their usage and can't seem to store a Custom Claim name and value.  E.G. I want to store a Claim name called CustomerID with the Value of ABC123, but, based on examples I can find, I can only store the claim name and not an actual value for it (as shown in this link).

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-create-a-custom-claim

    Claim c1 = new Claim ( "http://example.org/claims/simplecustomclaim", "Driver's License", Rights.PossessProperty);

    This code seems to indicate the user HAS a driver's License, but does not give the functionality to store the Drivers License ID.

    My scenario is, the users data can be stored in different databased depending on the company they work for and/or country.  I have a single database that contains all the user logon's for my site and the database name the customers data resides in.  When the user logins in, the database name is also queried and stored in a session variable for easy use within the site and various queries.  If the web server is restarted or the session information is reset, the user remains logged in but their Database name becomes blank and all pages start to error out. 

    I thought about adding code to lookup the user ID on the session start command and restore the database name.  That might work but I am also using session variables for other settings that the user can customize so, I need the user to be aware that they are having to log back in.
    Any ideas?

    Tuesday, July 11, 2017 7:39 PM
  • User-596903714 posted

    In an ideal situation, the Database Name and Company ID would live and die with the authenticated user but I need easy access to it and look it up in views and controllers.  I also need to be able to alter the Customer ID because some users can access multiple customer ID's.  The Customer ID associated with the user is considered the default/active Customer ID and used in the source for database queries etc.

    Tuesday, July 11, 2017 7:44 PM
  • User-1838255255 posted

    Hi Philld,

      If the web server is restarted or the session information is reset, the user remains logged in but their Database name becomes blank and all pages start to error out. 

    According to your description, you say the user remains logged after restart the web server. I want to know where are you store these values(user name and password)? If you store them in the local, like cookie, you also could add database name to cookie.

    Secondly, when you use data in the controller, you could add a check logical code in the controller. In this logical, if this database name is null, you could select it from the database then save it in the session.  

    Best Regards,

    Eric Du

    Wednesday, July 12, 2017 9:55 AM
  • User-596903714 posted

    This seems to be a common problem with people solving it in various ways by forcing log-off's and reloading information into the session etc but, I think I have figured out a great way to solve it.

    In the login code, I have been able to store some custom claims that hold the information in the same cookie as the user login.

    I don't know if you will need all of these references but, these are used in my Account Controller.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System.Threading;

    The Login Code looks like this (EDIT: I know the Database and CustomerID are hardcoded in this example but I did that for demonstration purposes):

    public ActionResult Login(string username, string password)
            {
                if (new UserManager().IsValid(username, password))
                {
                    var ident = new ClaimsIdentity(
                      new[] { 
                              // adding following 2 claim just for supporting default antiforgery provider
                              new Claim(ClaimTypes.NameIdentifier, username),
                              new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
    
                              new Claim(ClaimTypes.Name,username),
                              new Claim ("Database", "Data_023"),
                              new Claim ("CustomerID", "ABC123"),
    
                              // optionally you could add roles if any
                              //new Claim(ClaimTypes.Role, "RoleName"),
                              //new Claim(ClaimTypes.Role, "AnotherRole"),
                            },
                    DefaultAuthenticationTypes.ApplicationCookie);
    
                    var claimsPrincipal = new ClaimsPrincipal(ident);
                    // Set current principal
                    Thread.CurrentPrincipal = claimsPrincipal;
    
    
                    HttpContext.GetOwinContext().Authentication.SignIn(
                       new AuthenticationProperties { IsPersistent = false }, ident);
                    return RedirectToAction("Index", "Home"); // auth succeed 
                }
                // invalid username or password
                ModelState.AddModelError("", "invalid username or password");
                return View();
            }

    To read the claim information, you need to add the following references:

    using System.Security.Claims;
    using System.Threading;

    then

     //Get the current claims principal
     var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;
    
     // Get the claims values
     string claimvalue = ((System.Security.Claims.ClaimsIdentity)identity.Identity).FindFirst("Database").Value;

    I hope this helps someone in the same situation.  It seems to work for me and is simple to add new/custom claims.

    Wednesday, July 12, 2017 2:41 PM
  • User753101303 posted

    Hi,

    Yes or avoid as much as you can to directly use session variable. If this is an info that you can restore at any time use the session variable as a kind of "user cache".

    This way if the session variable is empty regardless of why, it will be just loaded again as needed.

    Monday, August 28, 2017 3:21 PM