I have written a .NET console app that fetches some values from an intranet web app using System.Net.WebClient with UseDefaultCredentials = true. The web app uses Windows Authentication and allows all users logged into the network and denies anonymous users:
<authentication mode="Windows"/>
<authorization>
<allow users="*" />
<deny users= "?"/>
</authorization>
The console app works fine when I run it on my PC by double-clicking on the program's EXE file. It does what it's supposed to do.
However, when the same program is run on the same PC as a scheduled task using TaskScheduler, it cannot establish communication with the intranet web app.
The console app is set to run under a particular user account —my own— the same account I'm using when double-clicking on the program's exe, and it is set to run whether the user is logged in or not. I have also tried with "Run with the highest privileges" enabled and disabled.
When configuring the task, TaskScheduler asks for the run-account password, which I supply. The option to prevent the password from being stored is not checked.
Is the problem here in the context of TaskScheduler that my WebClient subclass is set to use UseDefaultCredentials = true?
P.S. I should also add that the program's Main() routine is testing for command line arguments and assuming that if they exist, args[1] and args[2] contain particular values it needs and if not, it uses default values. Does TaskScheduler supply any command line arguments to the executables it launches? I am assuming that it does not do so.
Related
I am trying to record an internal website for which i need to enter credentials that is not same as the windows credential. Later on the same test needs to be run for more than one user. i know how to use the csv file to pass the parameters - username and password.
For Windows Authentication i have added Authorization manager.
From Fiddler i checked it was NTLM authentication(though i am not sure yet) and i did enter the values for NTLM authentication in Authorization Manager.
Now when i try and record the internal website - i cannot even go to homepage after the windows credentials, it keeps on spinning.
When i check the Authorization Manager, i find an extra line added for kerberos Authentication as shown in Picture:
My query here is:
1)why is it recording it as kerberos
2)where is it saving the username and password
3)why is it not loading the website- always keeps spinning and i have to stop it
4)I have tried Kerberos settings and then record, but its not working either , could it be i am using the wrong values in the kerb5.conf file , how do i debug.
Kind of stuck at the moment.
Thanks for help!
If you're uncertain what authentication is being used under the hood - just ask around, application developers or network administrators should be aware of the external authentication scheme. You can also try using a 3rd-party tool like Kerberos Authentication Tester
I don't think you can record and replay Windows authentication so it makes sense to start recording some time after the login screen as long as you can login using JMeter
Looking into JMeter source
// if HEADER_AUTHORIZATION contains "Basic"
// then set Mechanism.BASIC_DIGEST, otherwise Mechanism.KERBEROS
In case of Kerberos credentials are saved directly in the HTTP Authorization Manager in form of ${AUTH_LOGIN} and ${AUTH_PASSWORD}, real credentials are not stored anywhere
Most probably your application doesn't receive valid authentication context therefore it cannot proceed
Add sun.security.krb5.debug=true line to system.properties file (lives in "bin" folder of your JMeter installation), JMeter restart will be required to pick the property up.
More information:
Windows Authentication with Apache JMeter
JAAS and Java GSS-API Tutorials
I am trying to port a MVC5 web application to Linux MonoDevelop.
The site is using FormsAuthenication, so on Login action I cal SetAuthCookie() and on my controllers the AuthorizeAttribute to ensure that only logged in users access the functionality.
This all works well while on Windows!
After porting to Mono and debugging with MonoDevelop, I see it is not working. Actually, after successful login, the user is redirected to Login page again.
I tried removing the [Authorize] attribute from HomeController, just to check what is happening and I realized that - when in HomeController action- the User.Identity.IsAuthenticated returns false. I suppose that is why I get the redirection to Login.
But why could it be that User.Identity.IsAuthenticated returns false?
I checked that the SetAuthCookie() on windows creates a .ASPXAUTH cookie in the http Context. On Linux it creates a .MONOAUTH cookie in the http Context.
I tried configuring the cookie name in web.config by:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" name=".ASPXAUTH" />
</authentication>
But this didn't work...
UPDATE
I realized that, on mono, the SetAuthCookie() runs succesfuly BUT the cookie is not there (by using Firefox cookie management). Yet, on debug, the Response.Cookies Collection incorporates the .ASPXAUTH cookie. It seems like it is unable to be generated on the client.
Check if anywhere in your code the FormsAuthentication.SignOut() is called.
I had a similar issue in mono and it was due to a difference in the cookie lifecycle, which caused an unwanted call to FormsAuthentication.SignOut() and destroyed the .ASPXAUTH cookie before it was actually created.
After upgrading from CF8 to CF10, moving all files and databases and jumping through all the configuration hoops, the new version of the site is up and running, but the authentication/login is not working.
Here are the environments:
Old server: ColdFusion Enterprise 8,0,1,195765
Operating System: Windows Vista*
OS Version: 6.0
Update Level: .... hf801-00007.jar
IIS Version: 7
(*not sure where that "Vista" comes from? The System Information says "Windows Server 2008 Datacenter without Hyper-V")
New server: ColdFusion Enterprise 10,0,11,285437
Tomcat Version: 7.0.23.0
Operating System: Windows Server 2008 R2
OS Version: 6.1
Update Level: .... chf10000011.jar
Adobe Driver Version: 4.1 (Build 0001)
IIS Version: 7.5
I have a pretty standard ColdFusion login system, using cfloginuser in Application.cfc. After I login on the old site, outputting #GetAuthUser()# prints my username to screen, and all my role-based rules work.
On the new server, outputting GetAuthUser() prints empty.
On the old site, cfdump var="#SESSION#" includes:
cfauthorization_kllcms dXNlcm5hbWU6cGFzc3dvcmQ6YXBwX25hbWU=
On the new site, CFDUMP of session does not show a cfauthorization_kllcms value at all. All other session values exist in both instances.
It is the exact same codebase, database structures, etc. Naturally, none of my role-based rules work, because they all depend on validation of getAuthUser() and IsUserInRole("x") conditionals.
I know the initial login process itself is working, because it is correctly setting session variables with user information, and they are available on subsequent requests. But none of the traditional cflogin data is available on subsequent calls.
Any ideas what might have changed?
UPDATE: Per Adam's suggestion (below) I set up 2 test apps, one on the old server, one on the new.
Old Server: http://cfloginold.cimhost.com/index.cfm
New Server: http://cflogin.cimhost.com/index.cfm
Use "test" and "demo982013" as user and password.
Append ?logout=true to the URL to logout and re-test. These two apps have exactly the same code, same database. I am dumping session and form values to screen, along with GetAuthUser() value.
The authentication method is pretty much exactly as outlined in Adobe's documentation, and I can share all relevant code here if necessary.
Note that in the "new" server, the form loads each time you visit the page, whether you have logged in or not. This is exemplar of the fact that the cflogin session is not being retained or recognized, thus presenting the login form each visit (although not on initial form completion, which shows that cflogin is at least working on the initial login, I think).
UPDATE 2:
I've been drilling deeper into this, and I am able to get cfloginuser to fire a couple of ways, just not as part of the standard Adobe documented application-based user security model.
Option 1: I created a standalone page, and placed the following code in it:
<cflogin><cfloginuser name="directtest" Password = "2519D6025B5191F754D01BE163972628" roles="1"></cflogin>
I then instructed Application.cfc to allow this past the cflogin gate. You can see the results by pointing your browser to: http://cflogin.cimhost.com/directlogin.cfm?bypass=true
Voila. 'cfauthorization_cicmstest' value has been set, and user is logged in. Subsequent calls to GetAuthUser() are successful. So I know now that CF10 and the application do allow cfloginuser, and the user session can be created.
Option 2: I then decided maybe it was something about my Application.cfc file, so I again bypassed the cflogin gate, and placed the hard-coded cfloginuser snippet directly in my Application.cfc onRequestStart function. Logged out and visited: http://cflogin.cimhost.com/index.cfm?bypass=true&noquery=true
Again, cfauthorization_cicmstest value was successfully set, and user is logged in.
However, logging in still fails if the cfloginuser directive is fired within the actual cflogin process in Application.cfc. Here is what that code looks like:
<cfquery name="loginQuery" dataSource="mydatasource">
SELECT id,username, userroles
FROM myusertable
WHERE
username = '#cflogin.name#'
AND userpass = '#HASH(cflogin.password)#'
</cfquery>
<cfif loginQuery.userroles NEQ "">
<cfloginuser name="#cflogin.name#" Password="#cflogin.password#" roles="#loginQuery.userroles#">
<cfset MyMessage = "#MyMessage#<br />The Login Query fired and returned expected - loginQuery.userroles NEQ ''">
<cfelse>
<CFSET MyMessage = "Your login information is not valid. <a href='index.cfm?logout=1'>If your session timed out, click here!</a>">
<cfinclude template="loginform.cfm">
<cfabort>
</cfif>
I know that the query is successful, because I am setting an alert message that tells me the loginquery.userroles value was not empty, which is the condition for processing cfloginuser.
I know where the code is failing now, just not why. I've tried hard coding that cfloginuser value, and it still fails. I'm at a loss as to what to try next. The cfloginuser functionality works, just not in the one place (within the loginQuery.userroles conditional) that I need it to work.
UPDATE 3:
Just to prove to myself it wasn't my code, I created 2 more test sites, one on the old server, one on the new server:
New Server (CF10) = http://cf10loginadobe.cimhost.com/securitytest.cfm
Old Server (CF8) = http://cf8loginadobe.cimhost.com/securitytest.cfm
I copied exactly Adobe's 3 files from their Application-based security example. I created a database table with their schema and values. I added my cfdump outputs to show the sessions being created.
Test with user of "Bob" and password of "secret". Even with Adobe's own code, the tests fail on CF10.
I'm not sure what to do next. Rewriting the application to not use cfloginuser is not an option, as we have more than a dozen applications we are migrating to CF10 that use this authentication model, across hundreds of templates.
It's possible it's something weird about how IIS7.5 is handling ColdFusion requests, but that seems unlikely given the ability to successfully instantiate cfloginuser outside of the query result conditional.
ColdFusion 10 Application Based User Security Is Broken
I have deployed two test sites, using Adobe's own example code for application based user security, copied in its entirety from the Adobe website. One test site is in ColdFusion 8, one is ColdFusion 10. The code and databases are identical on both sites. I added cfdump output to monitor session variables and login status as they are set.
Test Site ColdFusion 8: http://cf8loginadobe.cimhost.com/securitytest.cfm
Test Site ColdFusion 10: http://cf10loginadobe.cimhost.com/securitytest.cfm
Logging in using a user of "Bob" and password of "secret" demonstrates the failure in CF10. Initially it appears login was successful, but note that the cfdump of the session does not show a cfauthorization_orders value in CF10, where in CF8 the value is present.
In CF8 subsequent visits to the same URL after login correctly retain the logged in user status and do not present the login form. In CF10, no session was actually created for the user, and therefore subsequent visits to the same URL prompt for login again.
I have tested this thoroughly, including bypassing the cflogin logic and forcing cfloginuser, which successfully creates an authenticated user in CF10, demonstrating that cfloginuser is supported.
It appears to me there is something about CF10's handling of the OnRequestStart function in Application.cfc that creates and then immediately kills the user session.
Workaround: The inelegant workaround I am using involves re-creating the cfloginuser session instantiation in a subsequent OnRequest function in Application.cfc. The code is as follows:
<cffunction name="onRequest">
<cfargument name = "targetPage" type="String" required=true/>
<cfinclude template=#Arguments.targetPage#>
<cfif IsDefined("loginQuery")>
<cfif loginQuery.userroles NEQ "">
<cflogin><cfloginuser name="#loginQuery.username#" Password = "#loginQuery.userpass#" roles="#loginQuery.userroles#"></cflogin>
</cfif>
</cfif>
</cffunction>
If there was an attempt to login in the OnRequestStart, I leverage the results of that request, check if it was valid (loginQuery.userroles NEQ ""), and then instantiate the authenticated session. There is a downside in that users have to click to a new page for logged in options to appear. The GetAuthUser() test is not met until another page load is requested.
Extensive testing of alternatives within Application.cfc did not reveal any alternative to this approach.
I'm updating one of our installers for .NET 4.0 and IIS 7.5, and one of the tasks is to switch the AppPool over to use its own identity. I have found this fairly trivial in WiX using the IIS Extension, but I'm struggling with two extra sets of permissions that we define, specifically to grant write permissions to the AppPool Identity:
<Directory Id="LOGS_LOCATION" Name="logs">
<!-- SourceDir\logs -->
<Component Id="LogsFolder" Guid="{3A7C38C7-6604-4063-A425-D62427B21AEE}" KeyPath="yes" DiskId="1">
<CreateFolder>
<!-- SYSTEM account is automatically given access, but set other ACEs here to avoid Users having access -->
<Permission User="Administrators" GenericAll="yes"/>
<Permission User="[ASPNET_USER]" Domain="[ASPNET_DOMAIN]" GenericRead="yes" GenericWrite="yes" Read="yes" Delete="yes" DeleteChild="yes" Traverse="yes"/>
<!-- IIS5: ASPNET, IIS6: NetworkService, IIS7: AppPool identity -->
</CreateFolder>
</Component>
</Directory>
ASPNET_USER and ASPNET_DOMAIN are defined to be AppPoolName and IIS APPPOOL respectively (where AppPoolName exactly matches the name of the App Pool).
When I run the installer, I get a 1609 error stating that IIS APPOOL\AppPoolName is not a valid identity and the installation fails. How can I specify the App Pool Identity to the Permission element so that the web app can write to the logs directory? Do I need to use a different identity?
That's an interesting question.
When you author a Permission element, it results in the record(s) of the LockPermissions MSI table. According to the MSDN, the records in this table are served by the InstallFiles, CreateFolders and WriteRegistryValues actions. When CreateFolder element is a parent, it's obviously CreateFolders action.
The security account corresponding to the ApplicationPoolIdentity is created when the appropriate AppPool is created. Now, ConfigureIIs action is scheduled later in the sequence than CreateFolders. It obviously doesn't make any sense to move ConfigureIIs before CreateFolders.
I'm not sure this will work, but I would try the following:
Replace Permission element with PermissionEx element (the one from WiXUtilExtension). It covers the functionality of Permission, plus adds more flexibility (for instance, not overwriting the ACLs, but appending).
Move the SchedSecureObjects action (the one responsible for handling PermissionEx stuff) after ConfigureIIs action (the one responsible for IIS stuff) if it's not there already.
Now by the time permissions are to be set, the appropriate security account should exist. You might also want to play with the way you reference it, for instance, with or without the domain part.
My understanding was that if asp.net application wants to write file to file server, it needs to use impersonation. I use the support.microsoft.com/kb/306158#4 "Impersonate a Specific User in Code" to do it. But it didn't work. The GetLastError() was giving error code 1326 "Logon failure: unknown user name or bad password." ( as per msdn.microsoft.com/en-us/library/ms681385) Then, the only way it worked was I've to create user (My computer > manage > local user and groups > user) with same user name and password as the file server folder. Now, even if I removed the impersonation code, it still works. So, I'm confused. Why do we need impersonation? I'm using XP and windows 2008 server.
You don't need to use impersonation in order for ASP.NET to write files to the local server. You simply need to make sure that the identity that ASP.NET is using has permission to write to the location you're trying to write to.