0
votes

I would like to make a MVC Web Application that talks to a Web API application and use ADFS 3.0 (on Windows 2012 R2) for authentication.

I managed to make the MVC Web Application to authenticate using ADFS. and configured everything as shown in this article by Vittorio Bertocci

http://www.cloudidentity.com/blog/2013/10/25/securing-a-web-api-with-adfs-on-ws2012-r2-got-even-easier/

Now I use the latest pre release of AAL from nuget

Now after authenticating with ADFS from web MVC app, I try to call the webapi

public async Task<String> CallSecuredAPI()
        {
            string authority = "https://fs.domain.com/adfs";
            string resourceURI = "https://{hostheader}/SecuredAPI";
            string clientID = "ExternalWebSite1";
            string clientReturnURI = "https://{hostheader}/ExternalSite";

            AuthenticationContext ac = new AuthenticationContext(authority, false);
            AuthenticationResult ar = ac.AcquireToken(resourceURI, clientID, new   Uri(clientReturnURI));

            string authHeader = ar.CreateAuthorizationHeader();
            var client = new HttpClient();
            HttpRequestMessage request =
                new HttpRequestMessage(HttpMethod.Get, "https://hostheader/SecuredAPI/api/Claims");
            request.Headers.TryAddWithoutValidation("Authorization", authHeader);
            HttpResponseMessage response = await client.SendAsync(request);
            string responseString = await response.Content.ReadAsStringAsync();
            return responseString;
        }

but I get this error which I think is with the client not being a UI based client or WPF , windows App. Can someone let me know whether I am doing something wrong.

![Error when trying to get Authorization code using AAL][1]

Server Error in '/ExternalSite' Application.

Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.

Source Error: 


Line 43: 
Line 44:             AuthenticationContext ac = new AuthenticationContext(authority, false);
Line 45:             AuthenticationResult ar = ac.AcquireToken(resourceURI, clientID, new Uri(clientReturnURI));
Line 46:             
Line 47:             string authHeader = ar.CreateAuthorizationHeader();

Source File: c:\Users\balakrishna.takkalla\Documents\Visual Studio 2013\Projects\ExternalSite\ExternalSite\Controllers\HomeController.cs    Line: 45 

Stack Trace: 


[InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.]
   System.Windows.Forms.Form.ShowDialog(IWin32Window owner) +5701502
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialog.ShowBrowser() +18
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialog.OnAuthenticate() +23
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialogBase.AuthenticateAAD(Uri requestUri, Uri callbackUri) +284
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.InteractiveWebUI.OnAuthenticate() +103
   Microsoft.IdentityModel.Clients.ActiveDirectory.OAuth2Request.SendAuthorizeRequest(Authenticator authenticator, String resource, Uri redirectUri, String clientId, String userId, PromptBehavior promptBehavior, String extraQueryParameters, IWebUI webUi, CallState callState) +363
   Microsoft.IdentityModel.Clients.ActiveDirectory.<>c__DisplayClass9b.<AcquireAuthorization>b__9a() +111
   System.Threading.Tasks.Task.Execute() +110
1
Did you read the error message? Not only does it tell you what went wrong, it tells you how to fix it. "Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application."Robert Harvey
Thanks Robert Harvey yes I did read it, was not sure I should go ahead and do the changes as I do not expect any pop-ups during this operation.Please let me know whether it is a valid error message that you are aware of.Bala Takkallapati
Your stack trace clearly says that some code is trying to open a modal dialog. I would try setting one of the styles as described in the error message so that you can see what the modal dialog is trying to show you. It's entirely possible that ServiceNotification will give you a log entry instead of a dialog, though I'm not really familiar enough with the ActiveDirectory operations that are going on there to be sure.Robert Harvey
Yes the code that is trying to open a windows message box from AAL library from Microsoft, and I have no access to change things as mentioned here as this needs to be applied as a overload on the MessageBox code. stackoverflow.com/questions/8928713/…Bala Takkallapati
I do think I have an understanding of what I am doing wrong, I think the AcquireToken is not the right method but AquireTokenSilent extensions should be used as I do not want the user entering the details. As the sample from cloudidentity was for a WPF and was ok to be prompted in that scenario.Bala Takkallapati

1 Answers

1
votes

if I understood correctly: you want to access a Web API from the code-behind of an MVC application. That topology is possible with Azure Active Directory today, you can see that in action in the sample https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet (I am in the process of updating it to the latest ADAL refresh, you can take a peek at the RCUpdate branch to see the work in progress).

However that topology is NOT achievable today from ADFS WS2012 R2. The reason is that an MVC app (and any other web site) is a confidential client, which OAuth2 handles differently from a public client (the WPF app you used as a starting point is a public client). In the scenario you are targeting, to use ADAL for getting a token from a confidential client you would use ADAL's method AcquireTokenByAuthorizationCode (see the sample I mentioned). However ADFS WS2012 R2 is incapable of processing that method. Today the OAuth2 support in ADFS WS2012 R2 is limited to public clients only.

Sorry for bringing bad news! As a mitigation, you might consider federating your ADFS with an AAD tenant: at that point you would be able to do what you want, authenticating as an ADFS user but getting tokens from AAD (which does support the necessary OAuth2 grant). HTH V.