Reputation: 2861
I'm using ASP.NET MVC 4 to build a simple intranet web app. I've put in place a login system and configure the RouteConfig.cs to display the login view as the "home page".
My question is simple : I've other views that "visitors" can't access if they're not logged. To perform tests, I try to access to these pages directly via the url and it works. How can I secure this by blocking the access to all the pages (excepted the login page)?
I've read things about the Web.config and authorizations but nothing worked. Any help guys?
EDIT : As Khanh TO told, working with the AutorizeAttribute is the best way to do it. However, I still have a little issue. When I'm logged as a simple user, I should not be able to see the admin pages (and that's the case) but when I attempt to do it, it redirects me to the login page (and I'm already logged !). I think this is because of the code below. The thing is, I would like to redirect to the home page if a user tries to attempt an unauthorized page. Possible to do that?
Here is the code I was speaking about :
<authentication mode="Forms">
<forms loginUrl="~/User/Login" timeout="2880" />
</authentication>
Also, I wanted to precise that my users are stored into a simple table in which the role is defined by a bool type (isAdmin to know if a user is an admin or not).
Upvotes: 2
Views: 9143
Reputation: 21
User authentication with ASP.NET Core using Cookie Authentication, checking credentials against an API during login and restricting access to authenticated users
Program.cs :
builder.Services.AddAuthentication((options) => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; in
options.DefaultSignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
// Set the default scheme used to challenge authentication
options.DefaultChallengeScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie((options) => {
// Set the login path where the user will be redirected for authentication
options.LoginPath = "/Home/Login";
// Set the access denied path where the user will be redirected when access is denied
options.AccessDeniedPath = "/Home/Index";
});
You can also add to the controller then user won't be able to access that controller without login
[Authorize]
public IActionResult Index()
{
return View();
}
Login :
[HttpPost]
public async Task<IActionResult> LoginAction([Bind("username,password")] UserLogin userLogin)
{
// Constructing the API URL for user authentication
string apiUrl = $"{_apiBaseUrl}/login/username={userLogin.username}/password={userLogin.password}";
// Sending a request to the authentication API
HttpResponseMessage response = await _httpClient.GetAsync(apiUrl);
// Checking if the authentication was successful
if (response.IsSuccessStatusCode)
{
// Setting a temporary data tag for the authenticated user
TempData["Tag"] = userLogin.username;
// Creating claims for user authentication
var claims = new List<Claim>
{
new Claim(userLogin.username, userLogin.password),
};
// Creating identity and principal for the authenticated user
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
// Signing in the user using cookie authentication
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
// Redirecting to the home page after successful authentication
return RedirectToAction("Index", "Home");
}
else
{
// Setting a temporary data for login error if authentication fails
TempData["LoginError"] = "Username or Password is Incorrect";
// Redirecting back to the login page with an error message
return RedirectToAction("Login", "Home");
}
}
Logout :
[HttpPost]
public async Task<IActionResult> Logout()
{
// Sign the user out using the specified authentication scheme.
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// Redirect the user to the login page after successful logout.
return RedirectToAction("Login", "Home");
}
Upvotes: 0
Reputation: 48972
If you need to selectively apply authorization for some pages, use AuthorizeAttribute on controller or action method:
Sample code:
[Authorize]
public class SecuredController : Controller
{
public ActionResult Index()
{
return View();
}
}
Or:
public class SecuredController : Controller
{
[Authorize]
public ActionResult Secure()
{
return View();
}
public ActionResult NonSecure()
{
return View();
}
}
Quoted from MSDN:
When you mark an action method with AuthorizeAttribute, access to that action method is restricted to users who are both authenticated and authorized. If you mark a controller with the attribute, all action methods in the controller are restricted.
The Authorize attribute lets you indicate that authorization is restricted to predefined roles or to individual users. This gives you a high degree of control over who is authorized to view any page on the site.
If an unauthorized user tries to access a method that is marked with the Authorize attribute, the MVC framework returns a 401 HTTP status code. If the site is configured to use ASP.NET forms authentication, the 401 status code causes the browser to redirect the user to the login page.
If you need to apply the authorize attribute globally except for the login page. You can add the AuthorizeAttribute to the global filter like this:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizeAttribute());
}
And apply AllowAnonymousAttribute to your login view:
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
}
In the web.config, enable Form Authentication:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Upvotes: 11