i have the following razor code to handle that only authenticated users can see the content. However i would like to bypass this if the user goes to Home/Login.
#if (Request.IsAuthenticated) {
#RenderBody()
}
Is this possible?
This shouldn't be done in your _Layout but in your controller/action with the [Authorize] attribute instead.
if you don't do it there, you're going to consistently see errors about RenderBody not being present on unauthenticated requests to other pages.
Sure, you could do something like this:
# {
var action = ViewContext.RouteData.GetRequiredString("action")
if (Request.IsAuthenticated || action == "Login")
#RenderBody()
}
Please add controller or action aurhorize attribute
[Authorize]
public class DefaultController : Controller
{
[Authorize]
public ActionResult Index()
{
...
}
}
or
#if (WebSecurity.IsAuthenticated)
{
#RenderBody()
}
Related
I am working on Asp.Net MVC application where I don't want to display define action name in url. So I am applying ActionName with Action in controllers. But when I am defining ActionName with Action then it's not working and showing error page of 404 - not found. So please can you guide me to resolve this issue ?
public ActionResult Login()
{
//code
}
when I am passing url like domain/Login then it's working properly.
[ActionName("SignIn")]
public ActionResult Login()
{
//Code
}
but when I am applying ActionName like above then it's showing error page of 404.
I check about this issue on google but not any work for me.
While returning from the controller , for the same controller you have to specify like
return View("Login");
If you are redirecting to another controller action
return RedirectToAction("ActionName", "ControllerName");
and if you are using javascript to navigate for this action,use like
window.location.href="/ControllerName/SignIn";
Try
[ActionName("SignIn")]
public ActionResult Login()
{
//Code
return View("Login");
}
I have a custom authorization header that checks to see if the current user has a certain permission before allowing the user to call the controller action.
[HasPermission(Permission.ViewPage]
public ActionResult Index()
{
return View();
}
The HasPermission class inherits from AuthorizeAttribute and overrides OnAuthorization like this:
public override void OnAuthorization(AuthorizationContext context)
{
if (!Permissions.IsUserInPermission(Permission))
{
context.Result = new ViewResult{ ViewName = "Forbidden" };
}
}
This works great with just about everything, except partial views.
When I put the authorization attribute on an action that returns a partial, the Forbidden view is returned, as expected, but it has the full layout. The full layout has all of the other elements on the page like the menu, so it looks like an iframe into another version of the site.
Is there a way to return a partial view when authorization fails on a controller action that returns a partial?
Or am I just doing this the wrong way?
Mark the action that is returning a PartialViewResult as [ChildActionOnly] then you can check for the context.Controller.ControllerContext.IsChildAction property in your filter OnAuthorization method
if (context.Controller.ControllerContext.IsChildAction)
{
context.Result = new PartialViewResult();
}
else
{
context.Result = new ViewResult();
}
I'm creating a new ASP.NET web application and I'm not planning on making use of the concept of "roles". I do, however, want to make sure a user is logged in on certain pages. Is there any existing attribute that simply checks if a user is logged in and redirects them or throws an error if they're not? Every search I've done points to using roles (such as this one).
The [Authorize] attribute will only return successfully if the user initiating the request is logged in and will only work on controllers and action methods.
It can be used to decorate a particular action:
public class FooController : Controller
{
// only FooAction requires authentication in FooController
[Authorize]
public async Task<ActionResult> FooAction()
{
}
public async Task<ActionResult> BarAction()
{
}
}
...or an entire controller:
// all actions in FooController require authentication
[Authorize]
public class FooController : Controller
{
public async Task<ActionResult> FooAction()
{
}
public async Task<ActionResult> BarAction()
{
}
}
You also have Request.IsAuthenticated which can be used on both action and non-action methods:
if (Request.IsAuthenticated) //or #if in Razor
{
//request is authenticated
}
...and even User.Identity.IsAuthenticated as #Darko correctly pointed out in his answer. Personally, I prefer Request.IsAuthenticated over User.Identity.IsAuthenticated as it also provides some useful null-checks for User and User.Identity. Here's how Request.IsAuthenticated looks under the hood:
public bool IsAuthenticated
{
get
{
return(_context.User != null
&& _context.User.Identity != null
&& _context.User.Identity.IsAuthenticated);
}
}
You can use User property, just put if() where it can control access and that's it.
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
Page.Title = "Home page for " + User.Identity.Name;
}
else
{
Page.Title = "Home page for guest user.";
}
}
This should work after you set the web.config . Here is the documentation https://msdn.microsoft.com/en-us/library/9wff0kyh(v=vs.85).aspx
I have this html in my asp.net MVC 4 application:
#if (User.Identity.IsAuthenticated)
<li class="login-link"> {
#Html.ActionLink(User.Identity.Name, "LogOff", "Account")
</li>
}
and this controller action
//[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
WebSecurity.Logout();
return RedirectToAction("Index", "Home");
}
but when i click log out link, user doesnt log out.
Please suggest how to fix it
In your code sample above, you wrote:
#if (User.Identity.IsAuthenticated)
<li class="login-link"> {
#Html.ActionLink(User.Identity.Name, "LogOff", "Account")
</li>
}
Based on how your #if (User.Identity.IsAuthenticated) statement resolves this may lead to some wonky code being rendered for the browser.
Does the following Razor code more correctly reflect your intent?
#if (User.Identity.IsAuthenticated)
{
<li class="login-link">
#Html.ActionLink(User.Identity.Name, "LogOff", "Account")
</li>
}
I couldn't find anything wrong with your code.
But try this and let me know if it works for you:
cshtml :
#Html.ActionLink("Log Off", "LogOff", "LogOn", null, new { #class = "actnclass" })
controller :
public ActionResult LogOff()
{
Request.Cookies.Remove("UserId");
FormsAuthentication.SignOut();
return RedirectToAction("LogOn", "LogOn");
}
Your Razor code looks good. Even a basic html logout code like the one below should do
Logout
Keep a breakpoint in your LogOff action in your Account controller and see what is happening. You seem to be using WebSecurity.Logout(); to logout and then redirect the user to the Home/Index page.
Also would like to know by looking at what are you inferring that user has not logged out.
Nothing wrong with you code. The point is the Action LogOff in Account is HttpPost Method, so it will only accept from a form submit.
You have to 3 ways to achieve Log off functionality
Change LogOff Method to HttpGet instead of HttpPost in Account Controller
Add an HttpGet overload for it take one parameter to leave the HttpPost method in Account Controller
[HttpGet]
public ActionResult LogOff(string token) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
// Already Exists
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff() {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
Use Javascript to submit the LogOff form
#using Microsoft.AspNet.Identity
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" }))
{
#Html.AntiForgeryToken()
// ...
LogOff
}
}
I would like to use the AntiForgeryToken function but the AcceptVerbs post does not apply. I am getting the anti forgery error. Is there a way to do this without the post method?
public ActionResult Page1(string data)
{ //code with view that includes link to Edit }
public ActionResult Page2(string data)
{ //code with view that includes link to Edit }
public ActionResult Edit(string pageName)
{ //execution then redirect to Page1/Page2 }
The anti forgery token works by a cookie and a hidden input field in the form. They both hold the same encrypted value. When the controller handles an action decorated with [ValidateAntiForgeryToken] it checks if the values in the cookie and the hidden input field match. If they don't - you get a nice exception.
You can use code like this
View:
<% using (var form = Html.BeginForm("DoSomething", "Default")) { %>
<%:Html.ValidationMessageFor(x => x) %>
<%:Html.AntiForgeryToken() %>
<%:Html.Hidden("a", 200) %>
<input type="submit" value="Go"/>
<%}%>
Controller:
public class DefaultController : Controller
{
public ActionResult Index()
{
return View();
}
[ValidateAntiForgeryToken]
public ActionResult DoSomething(int a)
{
return View("Index");
}
}
But then the form generated gets an method="post" attribute. On the controller side you don't need to specify [AcceptVerbs(HttpVerbs.Post)]. So the answer to your question is that you can use AntiForgeryToken without the AcceptVerbs attribute. You just need to use the POST method in the form.
To continue with the sample, if you specify [AcceptVerbs(HttpVerbs.Get)] on the action and Html.BeginForm("DoSomething", "Default", FormMethod.Get), the example won't work, because the GET request does not contain the cookie only the hidden input value gets encoded in the query string.