Search code examples
c#asp.net-core.net-coreasp.net-core-mvcasp.net-core-2.1

Asp.NET Core MVC Role based Authorization


I am developing role based authorization. After role is successfully defined with User.AddIdentity it disappears when I exit the page.

[AllowAnonymous]
[HttpPost]
public IActionResult Index(User user)
{
    try
    {
    var currentUser = _UserService.login(user, _context);                

    if (currentUser.userID != 0)
    {                                        
        CookieOptions options = new CookieOptions();
        options.Expires = DateTime.Now.AddDays(1);

        var identity = new ClaimsIdentity(new[] {
            new Claim(ClaimTypes.Name, currentUser.NAME_SURNAME),                                                
            new Claim(ClaimTypes.Role, "Admin")                        
        },
        "ApplicationCookie");    

        User.AddIdentity(new ClaimsIdentity(identity));

        var isin = User.IsInRole("Admin");

        var cacheValue = _UserService.stringToMd5(currentUser.NAME_SURNAME);
        Response.Cookies.Append("login_cache", cacheValue, options);                                    

        TempData["error"] = null;
        return RedirectToAction("index", "home");
    }
    else
    {
        TempData["error"] = "Kullanıcı adı yada şifre yanlıştır.";
        return RedirectToAction("index", "home");
    }                    
    }
    catch(Exception ex){
        TempData["error"] = ex.Message;
        //TempData["error"] = "User not found.";
        return RedirectToAction("index", "home");
    }
} 


[Area("Admin")]
[Authorize(Roles = "Admin")]
public class FaqController : Controller
{
    ....
}

Startup.cs

public void ConfigureServices(IServiceCollection services) 
{
    services.AddDistributedMemoryCache();
    services.AddSession();
    services.AddSession(options => {
    options.IdleTimeout = TimeSpan.FromMinutes(60);
});

    services.AddMvc();           

    services.AddDbContext<ModelContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseAuthentication();

    app.UseMvc(routes =>
{
    routes.MapRoute(
       name: "admin",
       template: "{area}/{controller=Home}/{action=Index}/{id?}");
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");               
});
}   

Solution

  • You haven't define how the authentication should work for your application. This should be done in the ConfigureServices method in Startup class. There you need to tell the framework to look for a cookie and from that authenticate the user.

    I have modify your cookie creation and added the default asp.net core way. I then enabled the cookie authentication by adding AddAuthentication() in the ConfigureServices method by this line

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
    

    Here's a full example

    [AllowAnonymous]
    [HttpPost]
    public IActionResult Index(User user)
    {
        try
        {
            var currentUser = _UserService.login(user, _context);                
            if (currentUser.userID != 0)
            {                                        
                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, currentUser.NAME_SURNAME),                                                
                    new Claim(ClaimTypes.Role, "Admin")      
                };
    
                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                var authProperties = new AuthenticationProperties
                {
                    ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1)
                };
    
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme, 
                    new ClaimsPrincipal(claimsIdentity), 
                    authProperties);
    
                return RedirectToAction("index", "home");
            }
            else
            {
                TempData["error"] = "Kullanıcı adı yada şifre yanlıştır.";
                return RedirectToAction("index", "home");
            }                    
        }
        catch(Exception ex){
            TempData["error"] = ex.Message;
            //TempData["error"] = "User not found.";
            return RedirectToAction("index", "home");
        }
    
    } 
    

    Then the startup

    public void ConfigureServices(IServiceCollection services) 
    {
        services.AddDistributedMemoryCache();
        services.AddSession();
        services.AddSession(options => {
            options.IdleTimeout = TimeSpan.FromMinutes(60);
        });
    
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
    
        services.AddMvc();           
    
        services.AddDbContext<ModelContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
    {
        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
    
        app.UseAuthentication();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
               name: "admin",
               template: "{area}/{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");               
        });
    }