ADFS 2.0 with ASP.NET MVC 4 - asp.net-mvc

I wanted to implement a small Proof of Concept for ADFS integration with MVC application. For this I created a virtual machine for Windows 2008 R2 and configured ADDS, ADCS and added my updated my server domain to one created one using ADDS.
After this I created certificate using ADCS.
Now, installed ADFS 2.0 using Microsoft download of ADFSSetup.exe RTW.
With help of some I configured ADFS & added relying party trust from my MVC application SSL URI.
After this I tried to run the application however started facing 403.14 error page.
Following observations as outcome from entire configuration:
I tried to access "<>/federationmetadata/2007-06/federationmetadata.xml" and I
got a proper XML which is as per expected.
I saw couple of entries from server computer - IIS website as like "http://<>/adfs/services/trust" OR "https://<>/adfs/ls/" however couldn't get any response from server. even I tried to access same from server using localhost instead of server names, then also no luck.
Then to cross-verify I checked IIS's default website where I found adfs/ls however it was a like a website. Not sure correct or not. I couldn't find anything 'services/trust' under ADFS IIS application.
After that I installed ADFS from Server manager and saw one more virtual directory 'fs',added under adfs application. when I tried to access 'fs' using https I am able to access it easily and can see SOAP service and page displayed with available web method.
I tried to find more on 'adfs/ls' and 'adfs/services/trust' however couldn't get much more information.
Please, if anyone came across this issue. Do let me know.

This is not an issue, this is how ADFS works. Next step you have to configure claims providers and relying parties from ADFS management console (from Admin tools). Relying party could be a sample claims aware MVC application. It should work

The only URL's that ADFS "answers" to are the federation metadata endpoint and the IDPInitiated one.
adfs/ls expects either WS-Federation or SAML parameters after it. On its own it will throw an error.
Then follow How To: Build Claims-Aware ASP.NET MVC Web Application Using WIF.
Why are you using Windows 2008 R2? (ADFS 2.0)? You should rather use Windows 2012 R2 (ADFS 3.0).

Related

Do I need to use the Windows Identity Federation Utility to create a claims-aware asp.net web application?

I built a claims-aware asp.net mvc application following the steps outlined in this page: https://learn.microsoft.com/en-us/dotnet/framework/security/how-to-build-claims-aware-aspnet-mvc-web-app-using-wif. The example in the page uses an STS on the local host, but in my application I am pointing to a fully-functioning AD FS on a different server.
I'm using Framework 4.7 and Windows Server 2016 to host the AD FS and to host the web application.
After I deployed the application I ran the Windows Identity Federation Utility against it (because I thought I needed it to add the application as a Relying Party Trust on the AD FS). This utility inserts a lot of tags into the web.config that refer to the Microsoft.IdentityModel namespace.
I then added the application as a Relying Party Trust to the AD FS, and navigated to the claims-aware app. The page failed because the sample code cast the claim returned by the STS as System.Security.Claims.Claim. When I changed it to cast as Microsoft.IdentityModel.Claims.Claim it worked fine.
The example I was following makes no mention of the Windows Identity Federation Utility. Do I need to use that? Or would this have worked without it?
When I try reversing the web.config changes that the utility inserted the site fails with a 401 error (access denied due to invalid credentials) so obviously the stuff inserted by the Utility is needed to get authentication from AD FS. Is this because I ran the Utility on the web site before adding it as a relying party trust to the ADFS?
The answer here is: don't run the Windows Identity Federation Utility if you are using ADFS Server 2016, as it forces use of the Microsoft.Identity libraries, which are deprecated. I mistakenly thought this utility was needed to create the FederationMetadata.xml file.
I created the FederationMetadata.xml file manually and reverted my web.config back to what it was before I ran the utility. This reverted me back to using the System.Identity libraries, which were added to the 4.5 framework, instead of the now-deprecated Microsoft.Identity libraries.
Just to note that the more "modern way" is to use the OWIN WS-Federation library.
This example is for Azure AD but you simply point to the metadata and the code figures all the rest out for itself.

404 error on azure for Asp.Net Web Api Project

I have deployed exact same solution on two servers, one is my own server in my basement and the other one is Microsoft Azure. The project is developed using Asp.Net Web Api 2.
On my own windows server running IIS 8.5 it totally works. For test, you can simply browse this link in your browser and see the error message {"Message":"The requested resource does not support http method 'GET'."} which shows the API has been hit.1
But exact same project on my Azure domain here, you just get a message saying
The resource you are looking for has been removed, had its name
changed, or is temporarily unavailable.
Everything about these two deployments is the same (to the best of my knowledge) and I was wondering if there is any further steps necessary on Web Api app deployment in MS Azure which I am missing.
I finally found the answer to this issue. If there are multiple apps deployed as one single website so each app is located in its own subfolder, you have to go to the configuration section of your web app on Azure and create virtual directories for each of those sub folders.
Ah, my problem was probably a common one. I was using
rootconfig = System.Web.Configuration.WebconfigurationManager.OpenWebConfiguration(null);
and that was returning the root web because the parameter was null.
When I ran it local that worked fine, but after I deployed the root Config was NOT what I wanted and my code was failing.
Switched to direct access via
stringVal = WebconfigurationManager.AppSettings["Foobar"].ToString();
Nice. Plus less overhead.

External HTTP requests from MVC application fail

I'm having problems making HTTP requests from my MVC.Net Intranet application. I encountered the problem when using the RestSharp library, but have boiled it down to a much simpler repro.
The following code:
using (var client = new WebClient())
{
var contents = client.DownloadString("http://www.google.com");
}
Will run successfully (on my local machine, debugging from Visual Studio 2013) inside a console app.
Will run successfully (on my local machine) from within LinqPad
Times out (on my local machine, debugging from Visual Studio 2013, hosted with IIS Express) when run from a controller action in a MVC intranet app.
This may be a duplicate of Not able to connect to website URLs from Asp.Net WebApi Action Methods (and is where I got the boiled down proof-of-problem code above) but in my case this is all running locally on my computer and it works fine from a console app.
I've tried various different code snippets, including using HttpClient instead of WebClient:
using(System.Net.Http.HttpClient c = new System.Net.Http.HttpClient())
{
var msg = c.GetAsync("http://www.google.com").Result.Content.ReadAsStringAsync().Result;
}
But I get the same, or similar results and errors in all cases. For the code above, I eventually get a 'TaskCancelled' exception, with no Inner Exception.
I've also got colleagues to try the same on their own machines, with the same results. I have read some similar questions, where people talk about problems with deadlock due to the SyncronizationContext in ASP applications, but that seems to relate to asynchronous calls. Here, as far as I can tell, everything I am doing is synchronous so I can't see how that applies.
In reality, I'm using the RestSharp library, which I've used to create a client library of my own for talking to the facebook API. I had tested this from a console app test-harness, which worked perfectly, but it all times out when I start using it inside my MVC app.
Has anyone seen this before and have any ideas on where I'm going wrong, or what the issue might be?
Is it to do with locking / deadlocking?
Could it be to do with permissions / proxy? We have quite strict web proxy rules at work, which are obviously configured correctly for my user. Could IIS Express hosting be changing the permissions or the user assigned to the app? The IIS Express service is running with my username at present.
UPDATE
I have tinkered some more and tried accessing an internal company web page instead of an external page (Google). I find that this works immediately - so that suggests strongly that it's to do with permissions or proxy settings.
Can anyone explain why this would be different between a console app and a MVC application?
UPDATE 2
I've run Fiddler to check the request and see what was happening to it. When fiddler is running the request succeeds.
This makes me think it's some strange permissions issue possibly? As a security measure, our login accounts don't have admin rights, instead we have a separate non-interactive account with admin permissions we can use to run apps that need admin rights, or install software etc. To get fiddler to capture traffic, I have to run it with this account.
Still, the calls work fine with my own normal account from the console app or LinqPad - so I guess my question becomes:
For an asp / MVC app locally hosted via IIS Express (Visual Studio Debugging), what user will this be run as, and what differences (if any) would there be to a console app?

Reading pst (Outlook) files from IIS ASP.NET application

I have to create sort of a .PST file based Web Mail.
I need to read all MailItems, Folders, Contacts and everything i can from PST files given by the user.
I am currently using DCOM interop to create a Application and use Session to add my file's stores.
My problem is that i can't even instantiate the Outlook.Application, the code simply doesn't run.
If i change to Visual Studio Development Web Server everything works as perfectly as expected, but if i change to local IIS Web Server.. nothing happens =/
What i did so far:
Set username and pass to impersonate on web.config
Set username and pass to inpersonate on my WebSite from iis -> Authentication -> ASP.NET impersonation
Added permissions to Everyone, Network Service, IIS_IUSRS, my user account in temp asp files, web site file and pst files i'm trying to read
Unfortunately I've already implemented all I need using TDD, so it would not be a good idea to change the way i'm doing this, like moving to NMapi or something.
Thanks in advance
EDIT:
As i've mentioned before, i I cannot use another library (and that one seems to work, but it's pretty expensive).
I only need this to run on a local server. It is a Web application, but for localhost ONLY.
It is not a good idea to use Outlook on the server side, as is described in detail here: http://support.microsoft.com/kb/257757
Microsoft does not currently recommend, and does not support,
Automation of Microsoft Office applications from any unattended,
non-interactive client application or component (including ASP,
ASP.NET, DCOM, and NT Services), because Office may exhibit unstable
behavior and/or deadlock when Office is run in this environment.
Maybe have a look at http://www.independentsoft.de/pst/

ASP MVC Preview 5 and IIS 6 Windows Authentication

I've just built a basic ASP MVC web site for deployment on our intranet. It expects users to be on the same domain as the IIS box and if you're not an authenticated Windows User, you should not get access.
I've just deployed this to IIS6 running on Server 2003 R2 SP2. The web app is configured with it's own pool with it's own pool user account. The IIS Directory Security options for the web app are set to "Windows Integrated Security" only and the web.config file has:
<authentication mode="Windows" />
From a Remote Desktop session on the IIS6 server itself, an IE7 browser window can successfully authenticate and navigate the web app if accessed via http://localhost/myapp.
However, also from the server, if accessed via the server's name (ie http://myserver/myapp) then IE7 presents a credentials dialog which after three attempts entering the correct credentials eventually returns "HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials".
The same problem occurs when a workstation browses to the web app url (naturally using the server's name and not "localhost").
The IIS6 server is a member of the only domain we have and has no firewall enabled.
Is there something I have failed to configure correctly for this to work?
Thanks,
I have tried the suggestions from Matt Ryan, Graphain, and Mike Dimmick to date without success. I have just built a virtual machine test lab with a Server 2003 DC and a separate server 2003 IIS6 server and I am able to replicate the problem.
I am seeing an entry in the IIS6 server's System Event Log the first time I try to access the site via the non-localhost url (ie http://iis/myapp). FQDN urls fail too.
Source: Kerberos, Event ID: 4
The kerberos client received a KRB_AP_ERR_MODIFIED error from the server host/iis.test.local. The target name used was HTTP/iis.test.local. This indicates that the password used to encrypt the kerberos service ticket is different than that on the target server. Commonly, this is due to identically named machine accounts in the target realm (TEST.LOCAL), and the client realm.
After extensive Googling I managed to find a solution on the following MSDN article:
How To: Create a Service Account for an ASP.NET 2.0 Application
Specifically the Additional Considerations section which describes "Creating Service Principal Names (SPNs) for Domain Accounts" using the setspn tool from the Windows Support Tools:
setspn -A HTTP/myserver MYDOMAIN\MyPoolUser
setspn -A HTTP/myserver.fqdn.com MYDOMAIN\MyPoolUser
This solved my problem on both my virtual test lab and my original problem server.
There is also an important note in the article that using Windows Authentication with custom pool users constrains the associated DNS name to be used by that pool only. That is, another pool with another identity would need to be associated with a different DNS name.
Sounds like the new Loopback check security feature of Windows Server 2003 SP1. As I understand it, is designed to prevent a particular type of interception attack.
From http://support.microsoft.com/kb/896861
SYMPTOMS
When you use the fully qualified domain name (FQDN) or a custom host header to browse a local Web site that is hosted on a computer that is running Microsoft Internet Information Services (IIS) 5.1 or IIS 6, you may receive an error message that resembles the following:
HTTP 401.1 - Unauthorized: Logon Failed
This issue occurs when the Web site uses Integrated Authentication and has a name that is mapped to the local loopback address.
Note You only receive this error message if you try to browse the Web site directly on the server. If you browse the Web site from a client computer, the Web site works as expected.
CAUSE
This issue occurs if you install Microsoft Windows XP Service Pack 2 (SP2) or Microsoft Windows Server 2003 Service Pack 1 (SP1). Windows XP SP2 and Windows Server 2003 SP1 include a loopback check security feature that is designed to help prevent reflection attacks on your computer. Therefore, authentication fails if the FQDN or the custom host header that you use does not match the local computer name.
Workaround
Method 1: Disable the loopback check
Method 2: Specify host names
See http://support.microsoft.com/kb/896861 for details.
Edit - just noticed that you said you were seeing this from Client PCs as well... that's more unusual. But I'd still look to test one of these workarounds, to see if it corrected the problem (and if so, might indicate a problem with your DNS config).
It sounds to me as though you've done everything right.
I'm sure you are but have you made sure you are using 'DOMAIN\user' as the user account and not just 'user'?
IE7 only sends Windows credentials (NTLM, Kerberos) if it identifies the server as being on the Intranet. IE7 also added an Intranet zone lockdown feature - if you're not on a domain, by default no servers are in the Intranet zone. This was done to prevent zone-migration attacks.
To change this, go to Tools/Internet Options, Security tab, then click Local Intranet. You can then manually add servers that should be treated as Intranet, by clicking the Sites button, then Advanced, or tell IE not to automatically detect your Intranet and selecting the other checkboxes as appropriate.
I just encountered the opposite problem - my site authenticates externally but not locally.
I compared it to the sites we have working and the difference was that the site that failed to authenticate was using Windows Authentication.
However, other sites I work with (this is a dev server) tend to have Basic Authentication.
Not sure why exactly but this fixed it.
However, at the same time I noticed "Default Domain" and "Realm" settings.
I know it's very unlikely but could these perhaps help at all?

Resources