I'm using wkhtmltopdf creating PDF from my html site. This works fine in development but when I upload it to the webserver with IIS7 I have the problem with the user.
In the site I use the windows authentification to log on the current user and also display the username on the site.
But the problem is that wenn the pdf is generating the current user isn't used so that I get an error. I don't want to use a temp-user for login (wkhtmltopdf.exe --username...) because this would be displayed on the website and also on the pdf.
Already tried the impersonate
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true"/>
</system.web>
but then I get
You are not authorized to view this page due to invalid authentication headers
I looked around and tried for a while but get no working solution for me to create a cookie or something like that and give it to wkhtmltopdf to create the pdf with the current user logged on.
Thanks for your help
If you are using Forms Authentication, you can use the --cookie option to pass the ASP.NET_SessionId cookie to wkhtmltopdf.
Related
I am using windows authentication impersonation in my MVC application.when i open the application the browser display a prompt for the credentials and validate the domain users.
But now i also want to create user in my application and also want to authenticate that users which is stored in my database.
Is it possible to authenticate Application DB users as well with windows authentication for domain users. i did much R & D on this but didn't found any solution yet. I will appreciate your suggestions. Thanks!
If I understand you correctly, you want to allow both Windows Authentication and Forms Authentication. This is not a common thing to do, but I have done it. Here is how I did it:
You have to use forms authentication as your primary authentication. So build the Forms Authentication as you normally would: you have a login page that, after submitting, validates the credentials from your database. The tricky part is adding Windows Authentication.
To do this, create one action in your authentication controller that uses Windows authentication. For this example, I'll assume your controller is AuthController and we'll call the action WinLogin. That action will look something like this:
[Authorize]
public ActionResult WinLogin() {
var principal = HttpContext.User;
if (principal == null || !principal.Identity.IsAuthenticated) {
//Windows authentication failed
return new HttpUnauthorizedResult();
}
// User is validated, so create the form authentication cookie
FormsAuthentication.SetAuthCookie(principal.Identity.Name, false);
return new EmptyResult();
}
It just checks if the user is validated and, if so, sets the Forms Authentication cookie with their AD username.
For that to use Windows Authentication, you have to update your web.config to tell it to use Windows Authentication for only that one action. You do that with a <location> tag:
<location path="Auth/WinLogin">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
By default, IIS won't let you change the authentication method at this place in the config. You need to update the "Feature Delegation" in IIS Manager to allow it.
In IIS Manager, click the server name on the left.
On the right, double-click "Feature Delegation" under the "Management" section.
Change both "Authentication - Anonymous" and "Authentication - Windows" to "Read/Write".
If you use IIS Express for debugging, you have to do something similar for that:
In the project folder, open the file .vs\config\applicationhost.config.
Modify these two lines so they say "Allow":
<section name="anonymousAuthentication" overrideModeDefault="Allow" />
<section name="windowsAuthentication" overrideModeDefault="Allow" />
Next update your login page to hide the username and password fields by default (let's say they are inside a box with an id of loginBox). The idea is that you perform an AJAX request to the WinLogin action, and if that succeeds, then you forward the user on to the main page or whichever page they were trying to go to. If you use jQuery, that will look something like this:
$.get("#Url.Action("WinLogin", "Auth")")
.done(function() {
//success! forward to the page they want
window.location.replace(returnUrl);
}).fail(function() {
//failed - show manual login prompt
$("#loginBox").show();
});
});
As long as your website is already a trusted website (which I assume so if you already have Windows Authentication working now), then the Windows Authentication will happen during that AJAX GET request.
Notice the use of window.location.replace(), which will not add the login page to the browser history, so if the user then hits the back button, they do not come back to the login page. It makes things a little more seamless.
You could also add a loading circle or something to indicate that the user should wait while that GET happens, but you can decide that.
With all this in place, the user experience should be:
They access a page.
They are not authenticated, so they get redirected to the login page.
The login page attempts the Windows Authentication in the background.
If the Windows Authentication succeeds, they are automatically redirected back to the page they wanted.
If Windows Authentication failed, the username and password boxes appear and they can login manually.
We have an application developed in Asp.Net MVC which uses session and Cookies. Which is declared in Web.config as -
<sessionState cookieless="true" regenerateExpiredSessionId="true" timeout="20"/>
Observation is, if we login in Chrome it generates a token in URL as
http://localhost:34343/(S(ypr1jdz2lk5ysiqearcracfj))/Home/Index
If the same url is copied in new Chrome window or in Internet explored, user still logged in and can see the home page.
In this case, we want user to logout and redirect to login page again if he copies the link from one browser to another browser window.
Can you please help with some references on this?
Thank You!
which uses session and Cookies.
You do not use cookies in your apllication because of this setting
cookieless="true"
URL contains sessionID and you can see it (S(ypr1jdz2lk5ysiqearcracfj)). If you send this url via another browser, your server application uses this parameter to find session and identificate user. If you change the settigns to
<sessionState cookieless="false" regenerateExpiredSessionId="true" timeout="20"/>
SessionID will be store in cookies and cannot be shared between different browsers. Of course if you start new window of the same browser, user will be still logged in.
I have an application where the root Default.aspx page is the login page. Logging
into the application works properly, and all other web pages are in subdirectories. Once on a subdirectory page, if the application times out, the application should return back to the root directory default.aspx for re-login. Instead it is trying to call a default page in the subdirectory which doesn't exist. Ex: /subdirA/subdirB/Default.aspx, when it should try to run just Default.aspx. Following is what I have in my web.config:
<authentication mode="Forms">
<forms loginUrl="/Default.aspx" timeout="10"/>
</authentication>
I have also tried "~Default.aspx", "~/Default.aspx", and "Default.aspx" none work.
I found some hints to add the following to appSettings:
This did not work either. Am at a loss, any help is appreciated!
Update
It looks like my application isn't using the loginUrl at all. I made a dummy front page for default.aspx, and moved the login page to /login/login.aspx, and changed the loginUrl to /login/login.aspx. Logged into the app and went to a page in a subdirectory, and let it timeout. It still tries to go to /subdirA/subdirB/Default.aspx. Why would it not use the loginUrl at all?
I found the issue - there was a redirect in the masterpage that was not working correctly. Changed this to ~/Default.aspx and is now working properly.
I have created new Project > ASP.NET Web Application (with individual user accounts). To root web.config I have added `
<authentication mode="Forms">
<forms loginUrl="log.aspx" defaultUrl="about.aspx"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>`
in order to redirect every not authenticated user to log.aspx (it exists in project root). But when I run my project now I got error
HTTP Error 404.15 - Not Found
The request filtering module is configured to deny a request where the
query string is too long.
Requested URL http://localhost:55371/Account/Login?ReturnUrl=%2FAccount%2FLogin%3FReturnUrl%3D%252FAccount%252FLogin%253FReturnUrl%253D%25252FAccount%25252FLogin%25253FReturnUrl%25253D%2525252FAccount%2525252FLogin%2525253FReturnUrl%2525253D%252525252FAccount%252525252FLogin%252525253FReturnUrl%252525253D%25252525252FAccount%25252525252FLogin%25252525253FReturnUrl%25252525253D%2525252525252FAccount%2525252525252FLogin%2525252525253FReturnUrl%2525252525253D%252525252525252FAccount%252525252525252FLogin%252525252525253FReturnUrl%252525252525253D%25252525252525252FAccount%25252525252525252FLogin%25252525252525253FReturnUrl%25252525252525253D%2525252525252525252FAccount%2525252525252525252FLogin%2525252525252525253FReturnUrl%2525252525252525253D%252525252525252525252FAccount%252525252525252525252FLogin%252525252525252525253FReturnUrl%252525252525252525253D%25252525252525252525252FAccount%25252525252525252525252FLogin%25252525252525252525253FReturnUrl%25252525252525252525253D%2525252525252525252525252FAccount%2525252525252525252525252FLogin%2525252525252525252525253FReturnUrl%2525252525252525252525253D%252525252525252525252525252FAccount%252525252525252525252525252FLogin%252525252525252525252525253FReturnUrl%252525252525252525252525253D%25252525252525252525252525252FAccount%25252525252525252525252525252FLogin%25252525252525252525252525253FReturnUrl%25252525252525252525252525253D%2525252525252525252525252525252FAccount%2525252525252525252525252525252FLogin%2525252525252525252525252525253FReturnUrl%2525252525252525252525252525253D%252525252525252525252525252525252FAccount%252525252525252525252525252525252FLogin%252525252525252525252525252525253FReturnUrl%252525252525252525252525252525253D%25252525252525252525252525252525252FAccount%25252525252525252525252525252525252FLogin%25252525252525252525252525252525253FReturnUrl%25252525252525252525252525252525253D%2525252525252525252525252525252525252FAccount%2525252525252525252525252525252525252FLogin%2525252525252525252525252525252525253FReturnUrl%2525252525252525252525252525252525253D%252525252525252525252525252525252525252FAbout.aspx
Physical Path
D:\Visual Studio workplace\WebApplication4\WebApplication4\Account\Login
Suggested fix is change maxquerystring so I did it as here. And then error changed
Exception Details: System.Web.HttpException: The length of the query string for this request exceeds the configured maxQueryStringLength value.
To me it looks like some infinite loop. Could you please tell me why the first error mentions /account/login which is default in this project? Also what is a solution in this situation?
I am using VS2015 with IIS Express.
When you select "Individual User Accounts" during project creation you are setting up authentication to use ASP.Net Identity which is a completely different system than Forms Authentication.
You don't want to mix them, use one or the other. But be aware Forms Auth is now much weaker security than Identity which basically sets up a modern Token server within your website.
I have seen this same error posted many times and as I have encountered the same problem myself and all of the answers were not helping me, until I found the real solution to the problem.
The original question says:
"I have created new Project > ASP.NET Web Application ..." and it says he changed the web.config file.
Indeed there is an infinite loop that is occuring because the web.config is set to deny access to any unauthenticated user to every page of the site that is including the login page itself! That is causing the loop.
In order to avoid the infinite loop one should grant access to at least the login page. I made that, placing another web.config file inside the folder where my login page is placed, and with the following code inside it:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</configuration>
This grants unauthorized access to all pages inside the folder, so be sure to put your login page there and that's all.
Edited: it is important to say that this approach is using Forms Authentication.
i m relatively new to C# and ASP.NET and I am having trouble designing an authentication system.
I have created a website where the user has to login, after which he can access various pages in this site. When the user clicks a logout link, he returns to the login page and is given the message "you have successfully logout." Now how do I prevent the user from typing the URL of one of the internal pages, bypassing my authentication? While working with PHP, I used session_start() and ob_end_flush() at the beginning and the end of each page to control authentication. What is a similar model in ASP.NET?
Also how do I include a .cs file from app_code folder to a aspx.cs?
If you are using FormsAuthentication, this is simple to do using configuration in web.config.
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="default.aspx" protection="All" path="/" slidingExpiration="true" timeout="60" />
</authentication>
This configuration forces aspx to ensure that all pages in the site can only be accessed by authorized users.
However, there is a logic problem with this configuration: no one would ever be able to login since they must be authorized to access any page in the site.
You can fix this, however, by opening "holes" in this protected by adding specific pages and indicating they can be authorized by anyone:
<location path="default.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Now how do i prevent re entry into the site by typing the url of the internal pages in the address bar.
How are you actually tracking the authentication? Forms authentication? Windows authentication? Something custom? Essentially, what you need to do is have those pages check for a valid authentication token. If no such token exists, redirect to the login page or an error or something to that effect.
You can do this by checking for authentication manually in the Page_Init method (which can access Session data, Cookies data, etc. where you'd store such a token), you can use various methods built-in, etc.
The concept is the same as it was in PHP, the tooling is just a little different.
While working with PHP i used session_start() and ob_end_flush() at the beginning and the end of each page.....What is it im supposed to use in c#?
You don't need to explicitly start/end session state in ASP.NET. Any code in the scope of the web application can access session state/values via System.Web.HttpContext.Current.Session. Any request coming from the same session will have this data associated with it.
Also how do i include .cs file from app_code folder to a aspx.cs
While in PHP you had to include files, in ASP.NET it's compiled code so the file isn't so important. What you need to reference is the namespace/class to use the code. For example...
If you have the following in a file in App_Code:
namespace MyApplicationCode
{
public class SomeCode
{
// stuff in the class
}
}
Then from any code within the application you should be able to use it by it's fully-qualified name (MyApplicationCode.SomeCode):
var someVariable = new MyApplicationCode.SomeCode();
Additionally, you can add a using statement in the header of the code file:
using MyApplicationCode;
And then access it directly:
var someVariable = new SomeCode();
When a user is successfully authenticated with his credentials, a cookie is set with a session id that corresponds to a file that stores value on the server. This cookie confirms to the server that the user is authenticated.
Check how your system handles sessions, it can be done without a session cookie, too:
(pseudo-code)
if (User.Login(formUsername, formPassword)) {
SetCookie ("LoggedIn", 1, Time() + 3600);
}
Now, whicever page needs a logged in user to be viewed, you just check if the user has the cookie set:
(pseudo-code)
if (CookieIsSet("LoggedIn")) {
// this page can be viewed
}
else {
Redirect ("/notAuthorized");
}
When you log the user out, you can delete the cookie by setting the expiration date in the past:
(pseudo-code)
SetCookie ("LoggedIn", 1, Time() - 3600);
Now, the user cannot view the internal page as the check (CookieIsSet(...)) will fail. Now, functions, methods and all the details depend on the system, but it always works like this:
if credentials are ok, set a cookie
whenever an internal page is visited, check if cookie is set
when logging out, delete the cookie
Hope this helps.
To check if the user typed in the address bar I would simply check the UrlReferer in page load of protected pages, other aspects should be controlled by web security and state management
if (Request.UrlReferrer == null)
Response.Redirect("errorpage.aspx");