Wednesday, November 30, 2011

MVC 3 and Azure ACS–Protect parts of the site

 

If you have worked with ADFS 2.0 or other claims based security models Azure’s Access Control Service (ACS) should not seem all the new to you. It is basically Azure’s hosted Secure Token Service (STS).

Recently I have been building an MVC 3 application and did not want my application to be forums protected. My personal opinion is that no one wants to create one off logins on the web anymore. To solve this I decided to use MVC 3 with ACS. Adding ACS to your MVC 3 project is not very hard and is explained in a few blogs on the net (here is a good one). You basically just use Visual Studio’s “Add STS” functional like you would for any other STS.

When you add the STS to your project it updates your web.config with information it needs for federation to work. By default it protects your entire website. This means you cannot even hit the login page without signing in. But what if I want unauthenticated people to read parts of my website, like the homepage? Well this is what I had to figure out. In the end it is pretty simple but given my newness to MVC and experience with using ADFS to protect WCF services I went down the wrong direction for awhile.

Your web.config is updated by the STS fedutil with the following information.

<location path="FederationMetadata">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
</location>
<system.web>
     <authorization>
        <deny users="?" />
      </authorization>

This does two things. 1) It tells the website not to protect the path to the federationmetadata. This allows the STS to get the information it needs. 2) It tells the site to deny access to all unauthenticated users (<deny users=”?”>). Since that node is not inside a location node that directive applies to the entire site, minus any location node directives.

Now if you want to unprotect certain areas of your site you might think you can just use some additional location nodes. Well this will send you down the wrong path with MVC. With a standard ASP.net or WCF app this could work but MVC adds a framework that causes this so it doesn’t work very well. In MVC 3 authorization is handled via the “authorize” attribute added to methods in controls or the controller class. In order to make sure you don’t open security holes this is really where you want to keep that control. If you add this attribute to a controller method, and it fails, the requests will fall into the Windows Identity Framework pipeline. The user will then be pushed to authenticate, IF, you change your config file a little.

Since the fedutil setup your web.config file to protect your entire site the website configuration will pick up the authorization requirement before it gets to any controller actions. So we need to change our web.config so it is not protecting anything. Update your web.config so it looks like the following:

 <location path="FederationMetadata">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
<system.web>

All we did was remove the authorization deny nodes from the web.config. This now opens up your entire site so nothing is protected by ACS. To start locking down your site you need to go into each of your controllers and start applying the Authorize attribute. For each method that has this attribute applied the site will fail over to your ACS (via the WIF pipeline) and request the user to login (unless of course they are already logged in).

Here is what a HomeController might look like:

 public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to MVC 3!!";

            return View();
        }

        [Authorize]
        public ActionResult About()
        {
            return View();
        }
    }

Notice how the About method has the authorize attribute. Now when this method is called (in the standard MVC 3 default template this is called via clicking on the about link in the navigation) the user will be directed to login if they have not already.

You can also apply the attribute to the entire controller if everything should be projected.

Saturday, November 12, 2011

Windows Phone and HTTPS service calls

 

If you have been working with Windows Phone and trying to make HTTPS based calls to other services there are a couple things you will want to know. Since these HTTPS calls happen over a secure connection there are a few nuances you have to be aware of. Windows Phone is pretty touchy about HTTPS certificates. Normally on a web page you can just create a self-signed cert and either bypass the cert trust warning or install the cert in to the machines trusted CA list. However, Windows Phone does not have this flexibility. During development or test you probably are using a self-signed cert. If your Windows Phone app calls a HTTPS service using a self-signed cert you will get an error saying “service not found” or “remote server returned a error: not found.” This is because the call is causing a certificate error since the cert is not in the phones trusted cert tree. To solve this problem the emulator or device needs to install the certificate. To do this just navigate to the .cer file in the device or emulator’s browser and tell it to install the cert. This will then let your phone make calls to the HTTPS service. Once you do this it should solve your problem.

The other issue you may see in production is that the cert you bought and installed works fine in Windows but not when called by Windows Phone. For some reason the CA trust tree for Windows and Windows Phone are not the same. Make sure you buy a cert from a CA trust that is in both.

Here is the list to help you find one:

Windows Phone CA trust

Windows CA trust

If you install a cert that is in the Windows trust tree but not in Windows Phone the phone will still give you an error when trying to call the HTTPS service because it does not trust the cert protecting the service.

Saturday, November 5, 2011

Understanding Azure Marketplace event flow

In working with the sample projects in the the Azure SDK I wanted to make sure I understood how the Marketplace event flow was happening. If you do the tutorial in the Azure 1.4 it helps you connect an application so it can handle subscription events from the marketplace. There is a lot of code created for you though. Once I got it working I still did not really understand what the event flow was happening from the Marketplace to my application. The solution? Spend some time digging through all the code and application flow and create a nice little Visio to help visualize it. Below is the diagram I created. Hopefully, if you have used the tutorial this will help you understand how the components you created and configured actually get wired together.

image

Friday, November 4, 2011

Azure Access Control - ACS50000: There was an error issuing a token.

 

I have been playing with the Azure Access control solution and how to put an application into the Azure Marketplace SaaS offering. The first issue I ran into was getting ACS to work. I had developed a solution with Microsoft’s Active Directory Federation services 2.0 before some the concept was familiar to me. Even through the topic was familiar to me federation errors are often still a pain to resolve.

The first thing you have to do is understand if the error is coming from the provider or client. In this case even though ACS is throwing the error the error is actually coming from the client as it is rejecting the token. It can be rejecting the token for a few reasons.

1) The certificate thumbprint the website is looking to validate against does not match. Check the sites web.config trusted issuers section and make sure the thumbprint matches what ACS has.

 <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <trustedIssuers>
        <add thumbprint="[yourthumbprint]" name="[yournamespace]" />
    </trustedIssuers>
</issuerNameRegistry>

Here is where you get the thumbprint from in the Azure ACS

image

If that does not work your wreply URL back to your website is not correct.

2) Check that the URL the token is being issued for (based on the wreply url) matches the audience URI configured in your application.

image

In my case I was in my development environment and therefore using odd port numbers. Once I updated the return URL so it had the port number of 444 and the audience URI in my web config to match it worked.

Tuesday, August 23, 2011

Security Config in IIS Express

I have gotten tired of always having to look this up or remember where it is at. That means it is time to post to my blog so I can find it easier and hopefully others can too.

If you are having issues with IIS Express authentication errors (like the Unauthorized 401.2 error I always get) here is some help. I can never remember what the last setting was I had IIS Express set to for authorization. To change IIS Express for windows auth or anonymous auth you want to work with the applicationhost.config file. It can be found here …Documents\IISExpress\config. You want to change the settings in the following area of the config file.

      <authentication>
        <anonymousAuthentication enabled="true" userName="" />
        <basicAuthentication enabled="false" />
        <clientCertificateMappingAuthentication enabled="false" />
        <digestAuthentication enabled="false" />
        <iisClientCertificateMappingAuthentication enabled="false">
        </iisClientCertificateMappingAuthentication>
        <windowsAuthentication enabled="false">
          <providers>
            <add value="Negotiate" />
            <add value="NTLM" />
          </providers>
        </windowsAuthentication>
     </authentication>

Tuesday, January 4, 2011

Sharepoint 2010, ADFS 2.0 and Roles

I actually copied this article from here. I have been working with ADFS a lot and know that before long this will come in handy so I wanted to save it on my blog.

February 6th, 2010 by Fredrik Lindström in ADFS, Windows Server 2008 R2

I’ve been tinkering quite a bit with Sharepoint 2010 and ADFS 2.0 lately and figured that this was worth sharing.

I followed the steps outlined in Travis Nielsen’s blog post to configure a federated identity provider in Sharepoint 2010 and configured ADFS 2.0 in my own way since our setup involves quite a few partner organizations. One thing that is not mentioned in the step by step guide is how to configure Sharepoint to accept role claims and assign access rights based on those claims.

The following Powershell snippet will do the trick

$issuer = Get-SPTrustedIdentityTokenIssuer
$issuer.ClaimTypes.Add(”http://schemas.microsoft.com/ws/2008/06/identity/claims/role“)
$map=New-SPClaimTypeMapping “http://schemas.microsoft.com/ws/2008/06/identity/claims/role” -IncomingClaimTypeDisplayName “Role” -SameAsIncoming
$issuer.AddClaimTypeInformation($map)
$issuer.Update()

After this the “Role” entry will show up in the people picker and you will be able to assign role claims to Sharepoint groups.