In my MVC 3 application I have a very basic controller
[HttpPost]
public ActionResult SignIn(LogonModel logonModel)
{
string logonMessage;
if(_authenticationService.Login(logonModel.UserName, logonModel.Password,
out logonMessage))
{
FormsAuthentication.SetAuthCookie(logonModel.UserName,true);
return RedirectToAction("Index", "Home");
}
return View();
}
I see the cookie getting set in the browser however when I close the browser and come back to the site, it is not logging me in automatically. It is almost like the cookie is not being processed, which it should be.
The first and most obvious question is: are cookies enabled in your browser?
What you could check as well is, whether in your web.config, you have configured the <authentication> section to have a timeout:
<authentication mode="Forms">
<forms loginUrl="~/login" timeout="60" />
</authentication>
if you don't specify a timeout it'll use the default value of 30 minutes, but maybe you set it to some other (invalid) value?
timeout attribute:
Specifies the time, in integer minutes, after which the cookie expires.
You could also check the CookiesSupported property (boolean) to see that that returns.
Be sure to remove the following <modules> tag from the web.config if using MVC 5+
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
I had a situation where the domain was wrong in the authenticaion section:
<authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="/user/login" protection="All" path="/" enableCrossAppRedirects="true" timeout="90" domain="WRONGDOMAIN.COM" />
</authentication>
Removing the domain did the trick:
<authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="/user/login" protection="All" path="/" enableCrossAppRedirects="true" timeout="90" />
</authentication>
Related
Currently I have program that provide SSE as a service, and I have to deploy on IIS. But its does not work correctly,
Here is the result when I run .exe without IIS.
data: Hello, world
But when its run behind IIS, Browser was stuck on loading.
I have to flush event Hello, world thousand times to make IIS flush result to browser and it's flush instantly instead of incremental update like SSE use to be.
Here is my web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath=".\sse_server.exe"
arguments="-port=%HTTP_PLATFORM_PORT% -environment development"
stdoutLogEnabled="false"
requestTimeout="00:05:00"
stdoutLogFile=".\sse_server_log">
</httpPlatform>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
</configuration>
Here is my go code
func SSEHello(rw http.ResponseWriter, flusher http.Flusher) {
rw.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Connection", "keep-alive")
rw.WriteHeader(http.StatusOK)
for i := 0; i < 1000; i++ {
rw.Write([]byte("data:Hello, world\n\n"))
flusher.Flush()
time.Sleep(time.Millisecond * 100)
}
}
Actually HttpPlatformHandler has 8kb output buffer , so my message is not sent out immediately.
I have to change HttpPlatformHandler to ASP.NET Core Module,
so web.config must update to this.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\sse_server.exe" />
</system.webServer>
</configuration>
And to start go 's application as aspNetCore on iis, the application need to get environment variable name ASPNETCORE_PORT then start http service on that port.
port := os.Getenv("ASPNETCORE_PORT")
http.ListenAndServe(":"+port, nil)
That's all!
My WebAPI method looks like this:
[Route("api/v1.0/Profile/Test/{offset}")]
public async Task<ServiceResult> GetTest(DateTimeOffset offset)
{
...
}
Calling it like this works:
http://localhost:54295/api/v1.0/Profile/Test/2016-04-05T13:30:44-11:00
However, this call won't work:
http://localhost:54295/api/v1.0/Profile/Test/2016-04-05T13:30:44+11:00
What's the trick here?
In my Web.config in the system.web section I have this entry:
<httpRuntime targetFramework="4.5" requestPathInvalidCharacters="<,>,%,&,*,\,?" />
I found a solution:
In my web.config in the system.webServer section I added this block:
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
Now the plus sign works as desired.
I'm trying to write an action in a webapi controllers to allow downloading a file.
But for some strange reason, the code doesn't works.
Here is my code:
<RoutePrefix("api/files")>
Public Class PermitFilesController
Inherits ApiController
<Route("download")>
public function GetFile() As HttpResponseMessage
Dim fStream as FileStream = File.Open("C:\Projects\1234.pdf", FileMode.Open, FileAccess.Read )
Dim response = Request.CreateResponse(HttpStatusCode.OK)
response.Content = new StreamContent(fStream)
'response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
'response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(fStream.Name)
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf")
return response
End Function
I try to download simply using the url in browser:
localhost:<myport>/api/files/download
The error (in Chrome ) is Error code: ERR_CONNECTION_RESET
In FF, it is even stranger: it redirects me to www.localhost.com:/... with the same error - connection reset by host
I put a breakpoint in my code, and I noticed the code gets called twice (as soon as I exit from trace from last line, it gets called again to the first line).
I have several other actions in this controller, and they all work ok.
Anyone having any idea what am I doing wrong?
EDIT
I started Fiddler, and now my browser shown this error:
[Fiddler] ReadResponse() failed: The server did not return a response
for this request. Server returned 0 bytes.
EDIT
I want to mention that webapi is integrated into a legacy classic asp.net application
The initialization code is as follows:
In global.asax.Application_Start
WebApiHelper.Initialize
....
....
Public Class WebApiHelper
Public Shared Sub Initialize()
GlobalConfiguration.Configuration.MessageHandlers.Add(New BasicAuthMessageHandler() With { _
.PrincipalProvider = New MPNAuthProvider() _
})
AreaRegistration.RegisterAllAreas()
WebApiConfig.Register(GlobalConfiguration.Configuration)
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
RouteConfig.RegisterRoutes(RouteTable.Routes)
GlobalConfiguration.Configuration.EnsureInitialized()
End Sub
....
MPNAuthProvider is used to ensure authenticated access to some webapi controllers
Public Class MPNAuthProvider
Implements IProviderPrincipal
Public Function CreatePrincipal(username As String, password As String) As IPrincipal Implements IProviderPrincipal.CreatePrincipal
Dim userID As Integer = 0
If Not UserData.ValidateUser(username, password, userID) Then Return Nothing
Dim identity = New GenericIdentity(userID)
Dim principal = New GenericPrincipal(identity, {"User"})
Return principal
End Function
End Class
Anything else I should check to see what happens?
Thank you
Initial Solution
After suggestion from Julien Jacobs, I tested my code into a separate, stand alone webapi project, and indeed the code proved to be correct.
So I started to investigate the web.config.
And I found the following settings that I had to comment out:
<system.web>
....
<httpModules>
<add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" />
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
</httpModules>
and
<modules runAllManagedModulesForAllRequests="true">
<remove name="RadUploadModule" />
<remove name="RadCompression" />
<add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" preCondition="integratedMode" />
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="integratedMode" />
</modules>
After I commented them, the code started to work ok.
But this proved to not be the ideal solution, so please read on...
Updated solution
After more tests with the application, I realized that RadCompression, while not absolutely required, is very useful to web applications with Telerik Ajax, because it provides transparent, on the fly compression for all ajax traffic (plus viewstate, is configured).
Because I disabled it, the application started to be slower.
So I had to find a way to re-enable RadCompression, but disable it for certain requests (like webapi endpoint for files download).
And the solution is:
Add special config section for RadCompression configuration
<configSections>
<sectionGroup name="telerik.web.ui">
<section name="radCompression" type="Telerik.Web.UI.RadCompressionConfigurationSection, Telerik.Web.UI, PublicKeyToken=121fae78165ba3d4" allowDefinition="MachineToApplication" requirePermission="false"/>
</sectionGroup>
....
</configSections>
Add handlers in system.web\httpModules
<system.web>
....
<httpModules>
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
</httpModules>
Add handlers in system.webServer\modules
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="managedHandler" />
</modules>
</system.webServer>
And the critical part, to disable RadCompression for specific requests (URIs), add a new config section as below
<telerik.web.ui>
<radCompression enablePostbackCompression="true">
<excludeHandlers>
<!--This will match every api/permitfiles/download file regardless of its location in the web site--> <add handlerPath="api/permitfiles/download" matchExact="false"/>
</excludeHandlers>
</radCompression>
</telerik.web.ui>
With those changes, RadCompression is empowered globally in the app for all requests, but restricted for specific requests (like webapi files download)
I'm using MVC 3 and FormsAuthentication:
<authentication mode="Forms">
<forms loginUrl="~/Account/" timeout="2880" />
</authentication>
My Account/Index page displays a login page, then using Jquery, it does a post to Account/Login to authenticate the user. Here's my AccountController action which handles it:
[HttpPost]
[Authorize(Users = "*")]
public ActionResult Login(string userName, string password) {
...
}
And the Jquery which posts to it:
$.post("/account/login", {
"userName": $("#userName").val(),
"password": $("#password").val()
}, function (data) {
...});
All the above works, but now I want to restrict general access to the site, so I added this to my root web.config:
<authorization>
<deny users="?" />
</authorization>
And in an attempt to allow access to the Account controller, I added this:
<location path="~/Account">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Here's my problem. I can view the login page (Account/Index), but I can't submit to Account/Login. When I watch what's going on through Fiddler, I get this text returned from the server when posting to that page:
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
It seems that when I add "~/Account" to the full authorized user list it isn't really working like it would in a non-mvc project. Is there a special way to do this in MVC 3?
The path to a controller is typically not referenced as a relative path. You should just be able to say location="Account", e.g.
<location path="Account">
Can't be sure that's your issue as I can't test it right now, but it could be...
Do not use the AuthorizeAttribute at all for the Login action. It makes no sense to require authorization for the authorization process itself.
To require authorization for all your Controllers you could create
[Authorize]
public class AuthorizeController : Controller
{
}
and extend all your Controllers from this one except the AccountController.
Hi all I know that this has been posted as a prior question several times, but I've gone through each question and their proposed solutions and I'm still not able to surmount my 404 issue. I'm running Elmah 1.1 32-bit. I've referred to ASP.NET MVC - Elmah not working and returning 404 page for elmah.axd but I haven't had any luck after applying the suggestions.
I'm running ASP.NET MVC 3. Here's my web.config:
...
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
...
<errorLog type="Elmah.SqlErrorLog, Elmah"
connectionStringName="dbconn" />
<errorFilter>
<test>
<jscript>
<expression>
<![CDATA[
// #assembly mscorlib
// #assembly System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// #import System.IO
// #import System.Web
HttpStatusCode == 404
|| BaseException instanceof FileNotFoundException
|| BaseException instanceof HttpRequestValidationException
/* Using RegExp below (see http://msdn.microsoft.com/en-us/library/h6e2eb7w.aspx) */
|| Context.Request.UserAgent.match(/crawler/i)
|| Context.Request.ServerVariables['REMOTE_ADDR'] == '127.0.0.1' // IPv4 only
]]>
</expression>
</jscript>
</test>
</errorFilter>
I have my .axd routes ignored using:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
I'm running the site on IIS7, 32 bit mode enabled. I've tried many different configuration options but all to no avail. Any ideas?
Thanks
Shan
My bad. My .axd ignore route rule was ordered after the default route mapping. The default route mapping rule was matching the URL elmah.axd. I guess I didn't realize that the ignore rules had to be listed above this route. Thanks everyone for your help!
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
} // Parameter defaults
);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Simply moving routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); before the Default route mapping resolved this issue.
Copy the .dll to your bin and reference... add the elmah defaults to configSections
Don't put the handler inside the system.webServer as mentioned above, try system.web section like this instead in your web.config.
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
</system.web>
just leave your global.asax as default:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
browse to the axd locally
then if working, lock it down with the config section Gedas mentioned above.
Have you tried this?
<configuration>
<system.webServer>
<handlers>
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
</system.webServer>
</configuration>
also make sure to secure elmah.axd location from regular users:
<location path="elmah.axd">
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
I was getting a 404 error due to the SQLServer Compact database being over the default max file size. Just deleted the SDF data file and 404 went away.
In asp.net mvc 3 global.asax.cs file
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
}
HandleErrorAttribute will swallow all exceptions, leaving nothing for ELMAH to handle.
See Joe's blog http://joel.net/wordpress/index.php/2011/02/logging-errors-with-elmah-in-asp-net-mvc3-part1/