3
votes

I would like to leverage ACS to authenticate Windows Account users (and eventually users from other identity providers in the future) on a website.

I have found a lot of resources regarding ACS, but most revolve around using WIF/using managed code in the UI layer in order to validate a user. I'd like to avoid that. Is it possible to retrieve a token from ACS by making a REST-based call to ACS using javascript/jQuery to retrieve a token for a Microsoft Account user?

One example that I saw that came close, is this link, however this uses a service identity instead of leveraging identity providers. http://code.msdn.microsoft.com/windowsazure/MVC4-Web-API-With-SWT-232d69da

Here's my end goal:

  1. This website would have two layers, a UI layer (MVC 4) and a service layer (MVC WebAPI). Both of these layers will need to scale independently of each other in Azure.
  2. I'd like to have the UI layer call ACS to determine if the current session is authenticated. If it is, I'd like ACS to return a token to the client. I'd like to store that token on the client as for use in step 3.
  3. Once the user has logged in, I'd like to have the client make a REST based calls to the service layer passing the Microsoft Account/ACS user token along in the header of each request, completely bypassing the UI layer for this second service request. The service layer would authenticate the user with each request.
  4. The client would handle the response codes (200, 401, ect) from the Service layer by either redirecting to the login page, or by displaying the results.

I am unsure about step 2. How would the client browser retrieve a token from ACS that it can pass along to the Service layer?

I essentially want to do what Vittorio describes here, but I want to use a MVC4 web app instead of a Windows 8 store app.

2
Thanks Rick and Sean. I was able to get a sln working with the link Rick provided to Vittorio's blog. I want to modify this sln to use a controller action to which the ReturnURL in the mgmt portal directs to store the token as a cookie. Then, I would make AJAX requests to the svc layer appending the token stored in the cookie to the header of each of those requests. The problem I'm having is that that action is not being redirected to upon login. I've updated the mgmt portal with the ReturnURL and refreshed the web.config using the "Identity and Access" tool. Am I missing something else?Paul
After login, fiddler shows that the client is directed to /Login/Return, but the response code is 302 with a location of /. Then the home page loads. The Return action in the Login controller never gets hit and the cookie that the return action in the login controller generates isn't present on the client afterwards. However, if I hit the return action on the login controller directly, the cookie is created.Paul

2 Answers

1
votes

In step 2, your MVC4 Web App is a relying party and therefore relies on the claims in the token presented by the subject/user. So, rather than the UI call ACS, it's really just redirecting the user to ACS for authentication. Anyway, based on your requirements and description, I believe this is the solution you're looking for.

http://blogs.msdn.com/b/vbertocci/archive/2013/01/09/using-the-jwt-handler-for-implementing-poor-man-s-delegation-actas.aspx

Hope this helps. -Rick

1
votes

I wrote up this answer before reading Vittorio's blog post that Rick linked to. That seems to pretty much what you want. I'll answer anyway to give some more context on WIF and how this scenario works, but you should check out that post.

First, it's important to note that when using WIF in your MVC 4 application, no authentication or validation is happening in the UI/presentation layer. WIF works at the request layer, and does a lot of things you would have to do yourself if you chose to go the Javascript route (which I don't think is a valid route, though it could probably be done with a lot of work).

It goes like this: When a user hits a page that requires authentication, WIF redirects them to to ACS, where you are then sent to Google/Microsoft to login (the identity provider). After you've authenticated with your identity provider, ACS then posts the resulting access token and claims about the authenticated user back to your application (the return URL in ACS configuration). Finally, WIF handles validating the token that was sent by ACS (no small task), and creates a ClaimsPrincipal object in your application that can be used to identify the user.

It sounds like what you want is impersonation/delegation, where a user logs in and their credentials get carried through from frontend to backend. For this situation, I see no reason why you shouldn't just use WIF for user authentication in your MVC 4 app. The user authenticates and WIF handles/validates the token (though because you're calling a web API you should probably use the JWTTokenHandler for its lightweight-ness). You create an Action in your MVC project that sends a request to your Web API with the token in the Authorization header. Your Web API gets configured to read the Authorization header of incoming request, uses JWTTokenHandler to validate the token, then you're done. You can steal much of the code for the Web API portion from this code sample (particularly the code in Global.asax.cs): http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf