Should I deploy Glimpse to the production site? - asp.net-mvc-3

I recently added the Glimpse Debugger package to my project. This added a reference to the Glimpse dll, and modified some Web.Config.
I like my project as much the same as possible on my development and production environment.
So is it save/wise to deploy Glimpse to my production site, or should I create a different project (or create branch from my csproj file) to keep it only locally?
Stuff that I'm worried about include:
Performance
Security breaches

I believe if the cookie for Glimpse is not found it doesn't load or do anything so performance should be negligible. Security wise you can just set a user restriction in the web.config for the location of the glimpse path.
<location path="Glimpse.axd" >
<system.web>
<authorization>
<allow users="Administrator" />
<deny users="*" />
</authorization>
</system.web>
</location>
Or if there is an administrator role you could do it by role instead of user name.
You can also switch it off if you don't want to rely on just the presence of the cookie. This easily achieved through web.config transforms, I haven't tested the markup yet but something like this should work.
<glimpse enabled="false" xdt:Transform="SetAttributes">
</glimpse>
UPDATE: Glimpse has seen some changes recently and (since 1.0 I believe?) the transform would now look as follows. Trying to set the enabled attribute will give a configuration error in the most recent version of Glimpse.
<glimpse defaultRuntimePolicy="Off" xdt:Transform="SetAttributes">
</glimpse>
As the documentation puts it...
Glimpse will never be allowed to do more with a Http response than is
specified in DefaultRuntimePolicy.
It should be noted that the only purpose this transform serves, is if you want to remove the ability to use Glimpse as part of your deployment process. If you want to conditionally disable it based on other criteria such as remote requests or authorization check, these are better done via policies. Glimpse operates off of a series of policies now (all based off of IRuntimePolicy), designed to help determine when glimpse should be allowed to do it's thing. In fact once Glimpse is installed, if you navigate to glimpse.axd, at the bottom of that page, you'll see a list of policies that are currently enabled. Such as the LocalPolicy that prevents it from being accessed by remote requests (configurably, any policy can be ignored via the web.config to allow remote requests) http://getglimpse.com/Help/Configuration. They also have a sample class called GlimpseSecurityPolicy that is included when you install Glimpse using Nuget, which you can use to add a authorization restrictions.
public class GlimpseSecurityPolicy:IRuntimePolicy
{
public RuntimePolicy Execute(IRuntimePolicyContext policyContext)
{
// You can perform a check like the one below to control Glimpse's permissions within your application.
// More information about RuntimePolicies can be found at http://getglimpse.com/Help/Custom-Runtime-Policy
var httpContext = policyContext.GetHttpContext();
if (httpContext.User != null && !httpContext.User.IsInRole("Glimpse")) //Once glimpse is turned on, you have to be a member of this Role to see the Glimpse Panel.
{
return RuntimePolicy.Off;
}
return RuntimePolicy.On;
}
public RuntimeEvent ExecuteOn
{
get { return RuntimeEvent.EndRequest; }
}
}
Now the policies are used to determine when glimpse should run, but they don't prevent the user from being able to bring up the glimpse.axd page. The cookie can still be enabled from what from what I can tell, but the cookie is meaningless if glimpse refuses to run in spite of the cookie being present. That being said It's still advisable to wrap the glimpse.axd page in an authorization check using the location tag in your web.config. Note that this is in addition to the GlimpseSecurityPolicy above.
<location path="glimpse.axd">
<system.web>
<authorization>
<allow roles="Glimpse" />
<deny users="*" />
</authorization>
</system.web>
</location>

Yarx is right on pretty much all fronts.
From a security perspective you could lock down the path using the method described. Only thing is, there are more URL end points that glimpse uses, so the rule would need to be something like *Glimpse/* (where * says that anything can come before it and anything can come after it). Once this is in place, glimpse should be pretty locked down.
Also, if in the config, you used the transform that Yarx provided, glimpse will never load, even if you have the cookie turned on.

Starting with Glimpse 1.7 there is a more generic way to secure ~/glimpse.axd with the additional benefit that you use the same policy for all. You simply need to make sure that your custom policy is called for resources too:
public RuntimeEvent ExecuteOn
{
// The bit flag that signals to Glimpse that it should run on either event
get { return RuntimeEvent.Endrequest | RuntimeEvent.ExecuteResource; }
}
Notice the | RuntimeEvent.ExecuteResource. See bottom of: Securing Glimpse.axd the way forward.

Related

Rotativa images and css works fine on localhost but is ignored in live server

Working locally the css and images are loaded in pdf correctly. But as soon as i migrate code on the server, these are not loaded in the generated pdf.
I am using ViewAsPDF(). There are some partial views in my code so I cannot use Server.Map.
Would really appreciate your help.
Regards
Old post I know, but hopefully can help someone in the future.
This situation can occur when your site uses windows authentication.
You need to give access to your CSS files in the web.config as follows:
<location path="content">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
You need the Rotativa folder in the root of the web app, or if different provide the path in web.config.
I had the same problem, fixed up by service account or server logon user name and password on ViewAsPdf customswitches.
eg.
return new ViewAsPdf("PdfInvoice", model)
{
CustomSwitches = string.Format("--username \"{1}\" --password \"{2}\" --footer-center \"Page [page] of [toPage] - {0}\" --footer-font-size \"8\" ", "Receipt Number :" + model.ReceiptId.ToString(), serviceAccountUsername.ToString(), serviceAccountPassword.ToString())
};

Owin with MVC 5 - Redirect loop - How to debug?

I had an MVC 4 application and coverted it into MVC 5 with hopes of using the OWIN middleware.
I succesfully updated to MVC 5 and implemented OWIN this article http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux.
When I access the application homepage I get redirected to the specified login URL, however then it starts redirecting to the login URL again until browser ends the attempt with a redirect loop error.
It seems like my login controller is regarded as if it needed authenticating even though there's no Authorize attribute set. I tried adding AllowAnonymous attribute but there was no change.
I have no idea how to debug what OWIN is doing, I set up several breakpoints throughout the app and it seems like my code is never accessed at any point so the redirects must happen at the middleware level.
Here's my OWIN config in the startup class:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login"),
LogoutPath = new PathString("/sign-out"),
SlidingExpiration = true,
ExpireTimeSpan = new TimeSpan(0,30,0),
AuthenticationMode = AuthenticationMode.Active
});
When I choose passive mode I just get an unauthorized error page, no redirects happen.
Any idea how to proceed in my scenario? Is there a way to debug what is happening?
Thanks for your help,
Vilem
I too was following the article you mentioned but found myself in a redirect loop despite my code matching the article code.
I fixed my redirect after a hint here http://forums.asp.net/t/1960987.aspx?After+converting+MVC+4+project+to+MVC+5+I+am+getting+an+error+this+website+has+redirect+loop+ which advised that IIS Express holds site specific authentication settings in a local config file.
If you are playing with different authentication settings, IIS Express
stored additional authentication settings in it's configuration file.
Something like:
<location path="WebApplication1">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
</location>
Configurations are in user's Documents folder
Documents\IISExpress\config\
and you should look for
applicationhost.config
Then just delete 'location' xml node
Adam
I became crazy for 1 day and in the end I created a new project and reported a view at a time, then a controller at a time until the error occurred.
I found that in the Layout page, there were some Action which was needed authentication and this was causing the redirect.
For example:
<a href="#Html.Action("Create","ads")" class="btn btn-primary navbar-btn btn-sm">
I have changed to:
<a href="/Create/ads" class="btn btn-primary navbar-btn btn-sm">
EDIT:
Upon later investigation the issue was caused by "SecuritySwitch" plugin. I had to remove it entirely, seems like it simply doesn't work with MVC5 + Owin.
ORIGINAL:
I solved this by installing Visual Studio 2013 trial (I use 2012 normally) and creating a new MVC5 project with individual user accounts authentication template set.
Then I started migrating my code piece by piece from the problematic project to this one hoping to find the breaking point. I did not find any, my code worked as I wanted when I migrated it fully.
Obviously this is not a real solution but it got the job done. Simply building the project from scratch saved hours/days of headaches.

reasons for being logged out before actual timeout in Forms Authentication

I have a asp.net MVC 3.0 website hosted on a subdomain of a main website . Asp.net version is set to .Net 4.0 integrated pipeLine .
the Forms Authentication settings is as below :
<authentication mode="Forms">
<forms
cookieless="UseCookies"
defaultUrl="~/home"
enableCrossAppRedirects="false"
path="/"
requireSSL="false"
loginUrl="~/account/login"
protection="All"
timeout="120"
slidingExpiration="true"
name=".SubDomainAuthCookie"></forms>
</authentication>
but it logs me out just after few minutes each time ! the Host Admins say that is maybe because of improper coding or heavy tasks that cause the application pool to reset , but it's a simple mvc website with EF ORM . I can't figure out what to do ! what should I look for as possible cause of this situation ?
Update :
after checking Application_Start , I find that it's the problem , I logged Application_Start() and the result is whenever I'm being logged out , a log is added .
12/6/2012 12:14:03 PM ==> Application started
12/6/2012 12:16:35 PM ==> Application started
12/6/2012 12:22:59 PM ==> Application started
strange ,but real . there is nothing complicated or heavy in the logic ! Could EF be the problem , does it consume a lot of memory/CPU that cause application pool to reset ?
Check there's no other application using name=".SubDomainAuthCookie". These applications can overwrite their cookies.
Are you using FormsAuthentication.SetAuthCookie before calling FormsAuthentication.RedirectFromLoginPage in login page? If not, probably authentication cookies are not set properly.
Try to log Application_End of global.asax.cs to know if your app is recycling too much.
protected void Application_End(object sender, EventArgs e)
{
/log the Application_End/
}
As mentioned by #ZippyV in one of the answers below, the reason behind this is that IIS is by default set to automatically generate a pair of keys for decryption and validating authorization cookie contents (as well as other things) on each AppPool recycle called MachineKey. Also mentioned in this question
When this key is changed, stored authorization cookie contents on all browsers is no longer readable and authorization is lost.
The most simple remedy is to use a static MachineKey in your web.config
Also try to set the cookies to be the parent domain. more info here.
I had this problem too when my hosting provider recycled my site's process too often. For some reason the authentication cookie becomes invalid because the encryption/decryption keys change. And so your site is not able to read the authentication cookie anymore.
You can solve this problem by specifying the keys in your web.config so that they can't get changed by your hosting provider:
Go to http://aspnetresources.com/tools/machineKey and click the button
Copy the generated tag
Open your web.config file and paste the generated tag inside <system.web>
You also want to set the expire time of cookie which has been generated while you log in.
And in form authentiction you have to use this.
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, //Here Userinformation, DateTime.Now, DateTime.Now.AddDays(1), false, string.Empty);
Here i have set the expire of cookie to DateTime.Now.AddDays(1) (loggin date+1day) so its too long it will be logged in.
So the created ticket will be expired on next day from when you logged in.
And in Web.Config
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
Now for a long time you can be logged in.
Hope it helps!!!
Check these links for deeper clarification on create loggin and expire time.
http://www.hanselman.com/blog/WeirdTimeoutsWithCustomASPNETFormsAuthentication.aspx
And
http://codeasp.net/blogs/vivek_iit/microsoft-net/848/forms-authentication-timeout-vs-session-state-timeout
Have you checked value in SessionState? It's default value is 20 Mins. You need to update it to same or greater than form authentication ticket.
Please add/update following tag in your configuration file.
**<sessionState timeout="120" />**

Why am I getting the "A potentially dangerous Request.Form value was detected from the client" error?

I've created a new ASP.NET MVC 3 / .NET Framework 4.0 site using the "Internet Application" template. I used Nuget to install the Windows Azure Web Role (MVC3) package and then followed the Access Control Service walkthrough to set up Windows Live ID and Google authentication.
Soon enough, I came across the "A potentially dangerous Request.Form value was detected from the client" error and followed the article in the Windows Identity Foundation wiki to try and resolve it. Unfortunately nothing I've tried works, including:
Setting <httpRuntime requestValidationMode="2.0"/> and <pages validateRequest="false"> in both the root web.config and Views\web.config
Copying SampleRequestValidator from the WIF SDK into the project and setting <httpRuntime requestValidationType="SampleRequestValidator"/> in both web.configs
I've also tried variations of these without success.
Any ideas?
Here's the complete exception:
Exception Details: System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").
Description: Request Validation has detected a potentially dangerous client input value, and processing of the request has been aborted. This value may indicate an attempt to compromise the security of your application, such as a cross-site scripting attack. To allow pages to override application request validation settings, set the requestValidationMode attribute in the httpRuntime configuration section to requestValidationMode="2.0". Example: <httpRuntime requestValidationMode="2.0" />. After setting this value, you can then disable request validation by setting validateRequest="false" in the Page directive or in the <pages> configuration section. However, it is strongly recommended that your application explicitly check all inputs in this case. For more information, see http://go.microsoft.com/fwlink/?LinkId=153133.
Stack Trace:
[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").]
System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8755668
System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +122
System.Web.HttpRequest.get_Form() +114
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.IsSignInResponse(HttpRequest request) +75
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.CanReadSignInResponse(HttpRequest request, Boolean onPage) +205
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.CanReadSignInResponse(HttpRequest request) +41
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +117
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
You might try decorating the controller action you are posting to (and the one which throws this exception) with the [ValidateInput(false)] attribute (by leaving <httpRuntime requestValidationMode="2.0"/> in web.config).
I had the same problem.
Here is an example of my solution:
[ValidateInput(false)]
public ActionResult *YourMethodName*(FormCollection forms)
{
// Encoded String
string EncodedValue = Server.HtmlEncode(forms[*name or index*]);
// Normal String
string value = forms[*name or index*]
//....
}
You don't need anything in your webconfig.
I wrote a small blog note on this here: http://erikbra.wordpress.com/2012/04/17/wif-saml-token-post-and-requestvalidationmode2-0/. It isn't necessary to turn off request validation, or set it to 2.0 for your entire site.
In short, you only need to alter the requestValidationMode to 2.0 mode on the specific URL that WIF posts back the SAML token to. This can be done with a element (see location Element (ASP.NET Settings Schema) for details) in your web.config, like this:
<location path="WIFHandler">
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
</location>
The “WIFHandler” location does not need to exist in your app, as WIF will shortcut the pipeline before ASP.NET tries to handle the request, and redirect you to the return url (ru in the wctx parameter of the SAML token POST) instead.
In your WIF configuration section of the web.config file, be sure to match the “reply” parameter with the location where you set request validation mode to 2.0 mode:
<microsoft.identityModel>
<service>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true"
issuer="https://localhost/STS/"
realm="https://localhost/MyApp/"
reply="https://localhost/MyApp/WIFHandler/" />
(...)
First - narrow where this is coming from. Use fiddler to investigate which field is causing the issue. Items as simple as: <s will cause this error when posted without being encoded. Also you may want to decorate your MODEL with the [AllowHtml] attribute and try not to enable 2.0 encoding - its a bit dangerous.
Copying SampleRequestValidator from the WIF SDK into the project and setting in both web.configs
This should fix it. Can you verify the code is actually executing? If you place a breakpoint in the Request validator, does it hit?
I assume you put <httpRuntime...> under <system.web> right?
I don't see any answer here mention this. so here it goes.
In addition to the " [ValidateInput(false)]", in your aspx, you might need to add this to your <%#Page ...>
<%# Page ValidateRequest="false">
This would allow disabling request validation on a per page basis instead of the whole web app.
I came across this problem when walking through the "Single Sign-On from Active Directory to a Windows Azure Application" tutorial. In my case, the problem was that I had inadvertently placed the <httpRuntime ... /> value in the wrong <system.web /> section in my web.config file (I didn't originally notice this, but there's a new <location> section with a path of "FederationMetadata" that also contains system.web.). The value should be placed in the top-level <system.web> section.
At first glance it looks like a bug in the Azure Mvc3 library. MVC 3 exposes special APIs that let you retrieve unvalidated values from the Form collection, but the module does not seem to be using them.
I haven't been able to find the technical reason why this doesn't work. However from a business requirements perspective, this is the wrong sample to base my particular solution on because it prompts for authentication before any pages can be accessed. However access to the home page needs to be anonymous so a "Log On" button can be used.
Instead I found the MVC3 Custom Login Sample that meets these requirements and it works.

Disable OutputCaching in MVC3 when running in DEBUG or under Debugger?

I am trying to disable output caching in a MVC3 app when in debug. I am specifying output caching in the controllers (via the attribute) but don't want to have to #if DEBUG all over my code. I expected this to work:
// In Web.config.debug
<system.web>
<caching>
<outputCache enableOutputCache="false"
xdt:Transform="Replace" />
</caching>
But this seems to be ignored. Any other ideas how to do it system wide without nasty global.asax code or #if DEBUGs everwhere?
The web.config.debug file is used only when you build a deployment package. If you run your site locally in Cassini for example it is completely ignored. So you may try disabling cache in your web.config:
<system.web>
<caching>
<outputCache enableOutputCache="false" />
</caching>
</system.web>
and in your web.config.release enable the cache. Note though that if you don't use the web deployment package feature those files are completely ignored.
I would think that would work as well. You may want to also try setting enableFragmentCache to false. Per this link:
the EnableFragmentCache property is
set to false, no page is cached on the
server, regardless of the settings in
# OutputCache directive or caching
profile used by the page. For more
information, see
OutputCacheSettingsSection and
OutputCacheProfile.
If you use IIS version > 7
You should:
<system.webServer>
<caching enabled="true"/> //false in webconfig.debug
</system.webServer>

Resources