Search code examples
c#asp.netasp.net-mvcasp.net-identityowin

Smart way for User Authorization (without creating table, etc.) in ASP.NET MVC


I use an external provider in order to authenticate user in my ASP.NET MVC app without any problem. However, I also need to authorize users in order to prevent them from direct access or expired access (session for 2 min). I had used ASP.NET Identity before, but this time I do not need to keep neither users nor roles on the table and for this reason I need a quick and good workaround for this problem. So, how can I prevent a user accessing the In dex page of my app without authenticating by the provider that I use. Similarly I also need to check if there is more than 2 minutes after user's last action and in such sitıuation I need to redirect user to Login page. I tried to use OWIN Cookie, but unfortunately I cannot logout user by using at least 10 different approach :(

Startup:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),

            //other options
            ExpireTimeSpan = TimeSpan.FromMinutes(1)
            //Provider = new CookieAuthenticationProvider(),
            //CookieName = "MyCookieName",
            //CookieHttpOnly = true
        });
    }
}

Controller:

[HttpGet]
public ActionResult Login(string code)
{
    //At this stage I want to force user to sign out, but none of the following methods work

    //method 1
    HttpContext.GetOwinContext().Authentication.SignOut("ApplicationCookie");

    //method 2
    var ctx = Request.GetOwinContext();
    var authManager = ctx.Authentication;
    authManager.SignOut("ApplicationCookie");
    //or        
    //authManager.SignOut();

    //method 3
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

    //method 4 (using only one of them at a time)
    Request.GetOwinContext().Authentication.SignOut();
    Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
    HttpContext.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);


    //check session
    var isAuthenticated = HttpContext.GetOwinContext().Authentication.User.Identity.IsAuthenticated; // >>> always returns true
    string tc = HttpContext.GetOwinContext().Authentication.User.Identity.Name; // >>> always returns name value


    //if user is authenticated via OAuth2.0
    if (user.isAuthenticated)
    {
        var claims = new[] {
        new Claim(ClaimTypes.Name, user.Name)
    };

        var identity = new ClaimsIdentity(claims, "ApplicationCookie");

        //// Add roles into claims
        //var roles = _roleService.GetByUserId(user.Id);
        //if (roles.Any())
        //{
        //    var roleClaims = roles.Select(r => new Claim(ClaimTypes.Role, r.Name));
        //    identity.AddClaims(roleClaims);
        //}

        var context = Request.GetOwinContext();
        var authManager = context.Authentication;

        authManager.SignIn(new AuthenticationProperties
        { IsPersistent = false }, identity); // ??? I am not sure if IsPersistent should be true ? 

        return View();
    }

    // login failed
    return RedirectToAction("Account", "Login");
}

Solution

  • Finally I have fixed the problem by using OWIN cookie authentication. Here is the code for those who might need to use OWIN cookie authentication on ASP.NET MVC.

    On the other hand, I would really like to integrate JWT to my ASP.NET MVC project, but unfortunately was not able to do. However, many thanks and voted up the answers that are also helpful for me.

    Startup:

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
    
    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            LogoutPath = new PathString("/Account/LogOff"),
            ExpireTimeSpan = TimeSpan.FromMinutes(5),
            SlidingExpiration = true,
            Provider = new CookieAuthenticationProvider(),
            CookieName = "YOUR_COOKIE_NAME",
            CookieHttpOnly = true,
            // !!! Using this setting "Always" causing "302 Redirect..." error while ddebugging >>>
            CookieSecure = CookieSecureOption.SameAsRequest 
        });
    }
    

    AccountController:

    public ActionResult Login()
    {
        //authenticate user
        var user = db.GetUser("John");
    
        if (user != null)
        {
            var claims = new[] {
                new Claim(ClaimTypes.Name, user.Name),
                new Claim(ClaimTypes.Email, user.Email)
                //you can add more claims
            };
    
            var identity = new ClaimsIdentity(claims, "ApplicationCookie");
    
            // Add roles into claims
            var roles = _roleService.GetByUserId(user.Id);
            if (roles.Any())
            {
                var roleClaims = roles.Select(r => new Claim(ClaimTypes.Role, r.Name));
                identity.AddClaims(roleClaims);
            }
    
            var context = Request.GetOwinContext();
            var authManager = context.Authentication;
    
            authManager.SignIn(new AuthenticationProperties
                { IsPersistent = true }, identity);
    
            return RedirectToAction("Index", "Home");
        }
        // login failed. 
        return RedirectToAction("Login", "Account");
    }