I have been have bad behavior at different times using this:
FormsAuthentication.SetAuthCookie(user.UserName, true);
How does/will .Net set the cookie otherwise?
I have tried this: (System.Web.HttpContext.Current.User.Identity.IsAuthenticated fails sometimes)
But my User.Identity.IsAuthenticated is always false
What gives?
First make sure that forms authentication is enabled in your web config file.
<authentication mode="Forms" />
Use code like below to make it work. The method RedirectFromLoginPage will create the authentication cookie as well as redirect the user to the original page or the default URL i.e. home page.
if (Membership.ValidateUser(userName, password))//or whatever method you use
{
// Log the user into the site
FormsAuthentication.RedirectFromLoginPage(userName, false);
}
Related
right now i work on an already existing ASP.NET MVC Project, which has the problem that the session sometimes suddenly ends and the user gets redirected to the login page. Today i noticed something, the login page is always loaded in the background:
I don't have much Experience with ASP.NET MVC so i wanted to ask, what could be the reason this always gets loaded. The code is not documented so i could not find a reason for it. I use IIS 8 for deploying.
Update:
I have now tracked with Fiddler and i saw something, at first i thought that the session cookies gets dropped or replaced turns out it doesnt. Its there even on the login page.
Update 2:
I have now validated that the cookie is still in place and the login info is still stored after this forced logout. Is there a common issue in ASP NET which can cause that a session is still saved but not recognized anymore? Turns out it could be this ActionFilter:
namespace backend.Models.ActionFilter
{
public class HasUserId : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Session.GetInt32("UserId") == null)
{
System.Diagnostics.Debug.WriteLine("Session is not there anymore");
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "Login", controller = "Account" }));
}
}
}
}
Update 3:
I think I have found the problem, the session state gets stored 'In-process' i have now changed it to 'State Service'. I hope this will solve my problem. Is it normal that the login still works even when the 'ASP NET State Service' is halted? This is my config:
<system.web>
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="20"
timeout="240">
</sessionState>
</system.web>
This problem occurs if the login page is as the start page. You can change this by modifying the filter file and specifically in routes.MapRoute.
For more information you can view here
If you want to change redirection via IIS, you can not do that.
The answer for my problem was to change the handling of the session state from 'In-process' to 'Out-of-process'.
I'm using Owin to host WebAPI Controllers. I have Owin middleware which performs authentication and sets the following if authentication fails:
context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
When this happens I want to display a HTML page with some instructions to the user. (Like, "You need to log on.")
At the moment I'm just redirecting the user to a accessdenied.html-page, but I would prefer if the access denied was shown directly without the user being redirected (I don't want the Location field in the web browser to change).
I assume I could just generate the HTML on the fly and adding it to the response, for example by reading the HTML content from a resource.
My question is: Is it possible to do display a custom access-denied error page automatically using configuration? In "traditioinal" ASP.NET, it was possible to set up customErrors in web.config, but this does not appear to work with Owin selfhost:
<customErrors>
<error statusCode="401" redirect="~/accessdenied.html"/>
</customErrors>
In a previous project of mine I had to use an Owin middleware like this:
app.Use((owinContext, next) =>
{
return next().ContinueWith(x =>
{
if (owinContext.Response.StatusCode == 500 /*or 401 , etc*/)
{
//owinContext.Response.Redirect(VirtualPathUtility.ToAbsolute("~/Home/Error"));
//this should work for self-host as well
owinContext.Response.Redirect(owinContext.Request.Uri.AbsoluteUri.Replace(request.Uri.PathAndQuery, request.PathBase + "/Home/Error"));
}
});
});
you have to register the middleware before all the others.
In this case I'm redirecting the user to an Error view, but as general practice I would say it's better to have an HTML static page.
Actually I think there's an extension request for handling global exceptions.
Have a look at this link...
I came across the same issue. I tried setting StatusCode and then doing Redirect to 401 page. But Redirect changes StatusCode to 302.
I came up with solution of reading 401.html writing it to Response. It worked for me.
context.Response.StatusCode = 401;
var path = HttpContext.Current.Server.MapPath("/401.html");
var html = System.IO.File.ReadAllText(path, Encoding.UTF8);
context.Response.Write(html);
owin provides you an option to redirect to your error page
context.Response.Redirect(errUrl); //context is the owinContext
You don't need to have any special RedirectResult or RedirectToAction Method.
Please bear with me as I am pretty new to designing websites.
When someone goes to my website they are initially sent to a log in page, which is defined in my web.config as:
<authentication mode="Forms">
<forms loginUrl="~/Login/Index" timeout="15"/>
</authentication>
However, before they log in I check whether the database they want to access has been defined (this is something that users may want to change frequently), and if it has not I want to send them to a different form. So, my login controller index looks like:
public ActionResult Index()
{
bool settingsSetUp = SupportLibrary.Settings.CompanyId != null;
if (settingsSetUp)
return View();
else
return RedirectToAction("index", "setup");
}
However, when I try this I always get "This page has a redirect loop" in Chrome. The page will not display in Firefox of IE either. On investigation the above method is always being called numerous times, so that eventually the browser decides it is being redirected too often. If I just set it to go to the view associated with the controller (no redirection) it calls the above method 15 times. Otherwise it is called 10 times before Chrome displays the error message.
Does anyone know why it is being called so many times as I think that is the root of the problem? Many thanks!
You are trying to load actions that require the user to be authenticated (they either have the Authorize attribute on them or it has been applied globally) which is causing a redirect back to the login action.
Check your actions to ensure that they can be accessed without being logged in if required.
I have an web service call where I get a list of 5 access codes, a user will be able to login with one of those codes(basically feel special that they have the code, but nothing secure about it, as they could share codes if they wanted to)
I would want to be able to use the [Authorize] if at all possible. Won't be using a database, just that one api call. Is this possible?
Check the codes on login with a simple if statement
if{code1 == "edgwreggw" || code2 == "etgwg"....)
{
FormsAuthentication.RedirectFromLoginPage(data.username, true);
}
else
{
login fail
}
Webconfig
<authentication mode="Forms">
<forms loginUrl="~/UserAuthentication/SignIn" timeout="10" defaultUrl="~\Home\Index" />
</authentication>
So.. you really don't care about security but you want to hand out 1 of 5 codes to random people to use your web service.
Simple enough. Put the codes in an array. Check if the code passed in is one of those values. If not, end the request. If it is, process the request.
I am trying to figure out why HttpContext.User.Identity.Name is returning blank.
Code
public ActionResult Test()
{
string username = HttpContext.User.Identity.Name;
return Content(username);
}
Am I using this in the wrong context? I am trying to get the user's username.
Web.Config
<authentication mode="Windows" />
IIS
I have enabled Anonymous and nothing else is checked. I am running IIS 6.0.
Is there any type of information I need to add to assist with figuring this out? I am pretty stuck. I checked this question but do I need to set a Cookie to make this work?
I have enabled Anonymous and nothing else is checked. I am running IIS
6.0.
This means that you won't be prompted to login, so User.Identity.IsAuthenticated will be false and User.Identity.Name will be blank.
Uncheck Anonymous Authentication and check Windows Authentication.
IsAuthenticated returns false, and thus Identity.Name returns empty string because you haven't required authentication for that action. You have to enable Windows Authentication and require authentication for the action. Try requiring that the user be authorized for the action by decorating it with the [Authorize] attribute - which will initiate the authentication negotiation.
[Authorize]
public ActionResult Test()
{
if(Request.IsAuthenticated)
{
string username = HttpContext.User.Identity.Name;
return Content(username);
}
else
{
return Content("User is not authenticated");
}
}
If anyone else is experiencing this issue, verify "Load User Profile" option is set to true. Go to IIS application pools. Select your app pool from the list. Click on Advanced Settings and scroll down to Process Model section.
This solved the problem in my case.
If you are using FormsAuthentication.SetAuthCookie
then you need to add
<authentication mode="Forms" />
to
<System.Web>
in Web.config file.
Solution from here