How to replicate Apache custom two-factor authentication on IIS? - iis

I've set up a small test server that does custom two-factor authentication on Apache, using a mechanism similar to this:
In <VirtualHost> file (of course, there are lots of other settings!):
<Location /2factor>
PerlAccessHandler Apache::TicketAccess
ErrorDocument 403 /perl/login.pl
</Location>
So, when I try to access a file in the /2factor directory I get redirected to a login script where I verify a user, password and TOTP from Google Authenticator, if an appropriate cookie is not present. This all works perfectly from both a browser and a smartphone app.
I've been asked to move this code to IIS, but all the example code I see uses either the browser's built-in authentication or LDAP-based solutions. How should I approach this? I'm not wedded to Perl; a C#-based method is perfectly acceptable.
Note, my test environment is just IIS 5.1 and XP.

Related

Protect Static Html Files Website in IIS with Basic Authentication

I have a simple Intranet Website that is just a few HTML pages with a little JavaScript and CSS.
If Allow Anonymous is ON, everyone can see it. It works.
In IIS, I turn on Basic Authentication and it only partially works as expected.
The company only allows IE and Edge installed on Windows 10 PCs for now.
Specific users have been added to that server running IIS.
In IE when users go to the website now, they are prompted for their username and password. Then the website loads.
However, in Edge, the users are never prompted for the their username and password. A 401 errors loads instead.
I have already tried putting the username and password in the URL like so: https://username:password#URL but that did not work.
I want the same or similar behavior that works in IE for Edge.
I assume you're using Edge Chromium browser, correct me if I'm wrong. The issue might be related with this policy: AuthSchemes.
You can visit edge://policy in Edge and check if it has an AuthSchemes policy set. The policy can be used to disable Basic Authentication. If your browser has this policy set, you need to enable 'basic' value in the policy.
I don't have this policy set and I visit the test page https://jigsaw.w3.org/HTTP/Basic/, the Basic Authentication works well in Edge.
You can also refer to this thread and this thread which have similar issues.

IIS 7.5, URL Rewrite 2.0, Kerberos - rewritten URL returning 401.1

I would appreciate any hints regarding the following issue:
The problem summary:
While using Negotiate:Kerberos in IIS 7.5, the authorization works correctly right until we setup URL rewriting (using the MS module "URL Rewrite 2.0") - any rewritten URL then returns "401.1 Unathorized" (requests not matching any rewrite rule keep working though).
The setup:
Windows Server 2008 R2 x64
IIS 7.5
URL Rewrite 2.0
Server is in a domain
SPN exists for HOST/hostname and HOST/hostname.domain (created by default)
Pool is using default ApplicationPoolIdentity (no custom account, not network service)
Kernel mode set to OFF
Authentication providers set to "Negotiate:Kerberos" only (no NTLM or annonymous)
URL Rewrite rule as as "^(.*)/$" => "index?x={R1}"
The result:
1) When accessing any URL not matching any URL rewrite pattern, Kerberos is working correctly, i.e. Kerberos ticket is issued (verified using klist), sent (verified using netmon and HTTP headers) and accepted (verified by URL being accessible and appropriate AUTH_USER property set to my domain account name) => no problem here.
2) When accessing any URL matching URL rewrite pattern, e.g. "hostname/foo" the result is:
HTTP Error 401.1 - Unauthorized
You do not have permission to view this directory or page using the credentials that you supplied.
Module WindowsAuthenticationModule
Notification AuthenticateRequest
Error Code 0x80070055
Requested URL http://hostname/index?x=foo
Physical Path D:\wwwroot\
Logon Method Not yet determined
Logon User Not yet determined
(if we try to access the rewritten URL directly, e.g. hostname/index?x=foo, Kerberos works again normally)
The attempts to solve it so far:
After googling, we have tried several options:
turning kernel mode ON: Kerberos stopped working completely, using either default pool identity or network service (I suppose we would need to setup additional HTTP SPN and/or use custom domain account with additional SPN for that account explicitly)
turning "useAppPoolCredentials" ON: no difference
enabling "Failing Request Tracing": surprisingly these failing 401.1 requests ARE NOT generating any output into the fail logs no matter what rule we try to setup (e.g. 400-999) - the folder is just empty (while other errors, like 404 or even handshake 401.x when accessing not-rewritten URLs are generating logs - very strange)
The conclusion:
So far we have reached a dead end - it may be some weird kind of "double hop" issue requiring using a custom domain account rather than default app pool identity, but as we're in fact accessing the same resources, it seems more like a URL Rewrite issue.
Any tips, hints, pointers? Anything would be highly appreciated.
Best regards,
Marek
we face the same issues as you do. By enabling extended error logging, we were able to put the finger on the actual problem, which seems to be a bug in the rewrite module (or at least in some part of IIS, which is related to the module):
When the URL gets rewritten, the access to the new rewritten URL is checked (seemingly hardcoded) using Basic Authentication and NTLM, neither of which has been configured on the Website at hand. The only configured authentication provider is Kerberos. Since the client doesnt send NTLM nor Basic credentials, there is no way this can work.
We (another person on the current project) are sending the issue to Microsoft. I will let you know, when I get any result.
It seems as though you have multiple issues here.
Failed-Request Tracing Logs
To fix your missing logs issue, you must make sure that the user that is running your site's AppllicationPool has read/modify rights to the folder where those logs are generated, otherwise you won't see anything. See the section labeled "Enable Failed-Request Tracing" on this page: Troubleshoot Failed Requests Using Tracing in IIS 7
What isn't clear is the fact that the site's Application Pool Identity (found in Advanced Settings for Application Pool) is the account that needs read/modify rights to that folder.
Once that is fixed you can load the XML logs in IE and see a much clearer picture of what is going on.
401.1 - Unauthorized Issue
A possible fix to your 401 error is to make sure unlisted file name extensions are allowed in Request Filtering. Go to IIS --> Sites --> [your site] --> Request Filtering
You have two options here:
Allow File Name Extension... and add the value "." (minus the quotes), see this answer.
Edit Feature Settings... and enabled the option "Allow unlisted file name extensions"
The 1st option should work well, the 2nd option obviously opens up a gaping hole but allows everything so you should be able to get it working.
I hope that helps.

Apache basic authentication with the username/password in the url

I'm using php to redirect users to a directory protected with apache basic authentication. I'm using the following url format to automatically log users into this directory:
http://username:password#www.somewebsite.com/protected.
This works fine in all browsers except IE, which no longer supports passing the username/password in the url.
Is there another way for a web application to automatically log a user into a directory protected with apache basic auth?
Update: If possible, please disregard the inherent downsides of using apache basic auth and http unless you are able to provide a viable alternative that addresses this question...namely how I can automatically log a user into a protected directory. This is for a client that is already using apache basic auth. Thanks :)
Microsoft has an detailed explanation of this issue including different workarounds in their knowledge base. This should get you on to a good start.
Please do also take a look at my comment about mixing HTTP with Basic Auth. You usually don't want to do this if security is an issue. Always use HTTPS because Basic Auth is not encrypted.

Can I unprotect a single script via .htaccess using CodeIgniter?

I'm in a development environment and we're using basic .htaccess/.htpasswd authentication to keep lurkers out. But some of my AJAX calls are coming back with HTTP/401 authentication failed errors. Is it possible for me to allow access only to those specific URL's? I can't easily do it by popping a new .htaccess in a subfolder because CodeIgniter uses ReWrites.
It's not possible to allow access only to those specific URL's. Unfortunately, .htaccess and .htpasswd authentication operates on a directory level only. And you're exactly right about why just using a subdirectory won't work - b/c of CI rewrites, which happen AFTER Apache has transferred control to CodeIgniter's index.php front controller.
The easy option, if you're working on something that (1) is not likely to be hacked in the first place, and (2) can't reveal sensitive data even if it is, is to use security via obscurity. Don't have any links to your dev site, include a noindex directive for search engine crawlers, and go on your merry way. This also has the advantage that you can test versions of the site with your colleagues and friends by just telling them the URL to go to.
If you're more worried about security, then you're probably building an auth module for your website's users. In that case, for your dev environment, just call that auth module in the constructor for all of your controllers, and redirect to the login page if the user is not logged in.
Good luck!

Digest authentication refuses to accept valid credentials

I'm trying to protect a folder with Digest Authentication through a .htaccess file:
AuthType Digest
AuthName "Restricted Area"
AuthUserFile /web/htdocs/www.domain.com/.../.htdigest
Require valid-user
I've created the file of passwords with the comand "htdigest".
All works fine on my local server ... but not on my remote server (hosted website)!
The browser shows the login panel even if I enter a correct password!
On the remote server PHP is running as CGI not as a module of Apache ... should be this the cause? Is there some workaround?
A Basic Authentication with .htaccess works fine on the same remote server!
If the script is running as CGI, that means it is running as the local user, not as www, which is probably the problem, yes. Is CGI the only option?
The code above is missing the AuthDigestDomain directive, about that the documentation says:
This directive should always be
specified and contain at least the
(set of) root URI(s) for this space.
Omitting to do so will cause the
client to send the Authorization
header for every request sent to this
server. Apart from increasing the size
of the request, it may also have a
detrimental effect on performance if
AuthDigestNcCheck is on.
However, I've definitely solved the problem by enabling the Apache module mod_auth_digest instead of the module mod_digest.

Resources