locked
Granting native application access to web application RRS feed

  • Question

  • Hi, I'm trying to setup a basic Azure AD scenario of having both a web application (ASP.net mvc / WebAPI) and a mobile application (Windows Phone, Windows 8, etc). For Win 8 I'm following the documentation Securing a Windows Store Application and REST Web Service Using Windows Azure AD (Preview). Everything goes fine otherwise but I cannot see the "Configure Web API Access for this Native Client Application" section in the configuration of native application. I assume it's been renamed to "Permissions to other applications"? Nevertheless, I cannot see my web application in the drop-down - it only shows "Windows Azure Active Directory" and "Windows Azure Service Management API".

    Do I need to modify the web application registration in some way to expose it to this list? What should I enter for the OAuth "resource" parameter in the login request? If I enter the web application Url, request fails with error "AADSTS50001: Resource <uri> is not registered for the account".

    Or is there something else that I'm missing?


    • Edited by htuomola Tuesday, March 11, 2014 9:24 AM more info
    Tuesday, March 11, 2014 9:23 AM

Answers

  • We've made some changes recently that we hope will provide richer capabilities and functionality.  Unfortunately we've struggled to get our documentation updated to account for these changes.

    We will be producing a blog posting on this which will have details on all the changes we've made (like enabling access to more APIs like Office 365 APIs all secured through AOuth 2.0 provided by Azure AD and a new consent framework).  However I'll just focus on the problem here to unblock you.

    You can write your own APIs and expose your permission scopes to other application developers as first-class peers of the Azure AD Graph, Azure Management and Office 365 APIs. You can do this by using another new preview experience by which you can download and upload a JSON file representation of your application’s identity configuration – known as the “application manifest”.  Exposing your permissions scopes can be done through the Windows Azure Management Portal, by clicking on the “Application Manifest” command bar button when viewing your application, downloading the application manifest, editing the “appPermissions” node in the manifest file (see below for an example of exposing a travel policy permission), and then uploading it, to re-configure your application.

    For your case, follow these steps:

    1. Download the app manifest for your web API as described above and save to a file

    2. Update the app manifest, replacing the "appPermissions" section with an edited version of the sample below. 

    Here's an example for "appPermissions" that you can use.  Please replace the claimValue, and the strings, and the permissionId as appropriate.  The strings are used in the consent dialogs (and other places) where permissions are shown to admins or end users.

      "appPermissions": [

        {

          "claimValue": "user_impersonation",

          "description": "Allow the application full access to the todo service on behalf of the signed-in user",

          "directAccessGrantTypes": [],

          "displayName": "Have full access to the todo service",

          "impersonationAccessGrantTypes": [

            {

              "impersonated": "User",

              "impersonator": "Application"

            }

          ],

          "isDisabled": false,

          "origin": "Application",

          "permissionId": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",

          "resourceScopeType": "Personal",

          "userConsentDescription": "Allow the application full access to the todo service on your behalf",

          "userConsentDisplayName": "Have full access to the todo service"

        }

      ],

    3.  Use the Manage Manifest control to upload your updated manifest for your web API. After upload, this will expose a new resource (your web API) and its single delegated permission that a client application can now be configured to select from (in the "permissions to other applications" section) 

    Then when a user signs up or begins using that client application, they’ll see a consent experience which lets them grant consent for the client application to access your API on behalf of the user or their organization (see below). After consent, as part of a client application’s request to your web API, it receives an access token (JWT) where the “scp” claim will contain the permissions that the user or organization granted to the client application.  For the example above, if the user granted “Set policy for travel”, the “scp” claim would contain the “user_impersonation” value.

    Hopefully this will help to unblock you.  Let us know if you need any further information


    Dan Kershaw [msft]


    Tuesday, March 11, 2014 11:07 PM

All replies

  • I'm having similar problem since couple of days, before that there was a section called "Client access" "Client Applications That can Access This Application" which has strangely disappeared. But if you refresh the page and scroll down fast before page loading is finished you can see this section appear grayed out and when the page is rendered it is removed. I guess WA team is busy upgrading services which I appreciate but removing functionality without prior announcement or not providing an alternative seems to be a hallmark of MS off late. 



    • Edited by padraj Tuesday, March 11, 2014 8:13 PM
    Tuesday, March 11, 2014 8:11 PM
  • We've made some changes recently that we hope will provide richer capabilities and functionality.  Unfortunately we've struggled to get our documentation updated to account for these changes.

    We will be producing a blog posting on this which will have details on all the changes we've made (like enabling access to more APIs like Office 365 APIs all secured through AOuth 2.0 provided by Azure AD and a new consent framework).  However I'll just focus on the problem here to unblock you.

    You can write your own APIs and expose your permission scopes to other application developers as first-class peers of the Azure AD Graph, Azure Management and Office 365 APIs. You can do this by using another new preview experience by which you can download and upload a JSON file representation of your application’s identity configuration – known as the “application manifest”.  Exposing your permissions scopes can be done through the Windows Azure Management Portal, by clicking on the “Application Manifest” command bar button when viewing your application, downloading the application manifest, editing the “appPermissions” node in the manifest file (see below for an example of exposing a travel policy permission), and then uploading it, to re-configure your application.

    For your case, follow these steps:

    1. Download the app manifest for your web API as described above and save to a file

    2. Update the app manifest, replacing the "appPermissions" section with an edited version of the sample below. 

    Here's an example for "appPermissions" that you can use.  Please replace the claimValue, and the strings, and the permissionId as appropriate.  The strings are used in the consent dialogs (and other places) where permissions are shown to admins or end users.

      "appPermissions": [

        {

          "claimValue": "user_impersonation",

          "description": "Allow the application full access to the todo service on behalf of the signed-in user",

          "directAccessGrantTypes": [],

          "displayName": "Have full access to the todo service",

          "impersonationAccessGrantTypes": [

            {

              "impersonated": "User",

              "impersonator": "Application"

            }

          ],

          "isDisabled": false,

          "origin": "Application",

          "permissionId": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",

          "resourceScopeType": "Personal",

          "userConsentDescription": "Allow the application full access to the todo service on your behalf",

          "userConsentDisplayName": "Have full access to the todo service"

        }

      ],

    3.  Use the Manage Manifest control to upload your updated manifest for your web API. After upload, this will expose a new resource (your web API) and its single delegated permission that a client application can now be configured to select from (in the "permissions to other applications" section) 

    Then when a user signs up or begins using that client application, they’ll see a consent experience which lets them grant consent for the client application to access your API on behalf of the user or their organization (see below). After consent, as part of a client application’s request to your web API, it receives an access token (JWT) where the “scp” claim will contain the permissions that the user or organization granted to the client application.  For the example above, if the user granted “Set policy for travel”, the “scp” claim would contain the “user_impersonation” value.

    Hopefully this will help to unblock you.  Let us know if you need any further information


    Dan Kershaw [msft]


    Tuesday, March 11, 2014 11:07 PM
  • I meant to add, that while this is a little more work, it does provide you with a little more power and flexibility here.  It allows you to expose a set of permissions of your choosing to match the functionality of your web API that client applications can choose from.  When the client calls your API you'll get a scp value in the access token that you can authorize the web API request against.

    Dan Kershaw [msft]

    Tuesday, March 11, 2014 11:14 PM
  • Thanks, I'll try that out and report the outcome here. I actually suspected that the manifest might be the key but as I didn't find any samples or documentation about the expected format, there was little I could do. On a side note, in the "Manage manifest -> Download manifest" the "learn more" link points to https://manage.windowsazure.com/AppManifestDownloadLearnMoreLink (which doesn't work, unsurprisingly).

    On a bit different topic, I was yesterday having an issue when trying to edit application definitions ( redirect URI to be specific). Using IE 11, the field is marked as changed but Save button didn't appear. Trying to navigate away without saving showed (correctly) a message box containing a warning about discarding changes. I changed to Google Chrome and was able to save my modifications :)

    Wednesday, March 12, 2014 7:08 AM
  • Hi Dan,

    Thanks for your prompt reply. My situation is a little different but I still tried out your solution but didn't help. When wanting to access the WebApi I get a screen asking for permissions
    -------------------------------------------
    OAuthClient needs permission to:
    Read directory data   

    Sign you in and read your profile (preview)   
    -----------------------------------------

    After clicking on "OK" I see a processing wheel and after a while the consent screen aborts the processing and nothing happens and when I click on "No thanks" an exception is raised.

    I will explain what I am trying to do/did before the WAAD upgrade.

    I have a MVC WebAPI exposing its functionaliteit and a MVC WebApp, both created in VS 2013 and authentication set to use "Organisational Accounts", in both the cases VS created necessary plumbing within the project and entries in the WAAD portal. The only change I did within the WAAD interface is that I used the now defunct functionality "Client Access" to set permissions on both MVC WebApp and MVC WebAPI apps. Actually setting permissions for MVC WebApp using the Client Access section created permissions for both WebApp and WebApi as I could select WebApi from the list of API's on which the WebApp had access to.

    Further I made changes to the WebApp code to access the WebApi, look at the code snippet below

    Snippet below courtesy MSDN

    --------------------------------------------------------------

       1:  public ActionResult About()
       2:  {
       3:    string authorizationUrl = string.Format(
       4:      "https://login.windows.net/{0}/oauth2/authorize?
                api-version=1.0&
                response_type=code&
                client_id={1}&
                resource={2}&
                redirect_uri={3}",
       5:      ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value,
       6:      AppPrincipalId,
       7:      "http://myadfsvagaries/webapi",
       8:      "https://localhost:44304/Home/CatchCode"
       9:    );
      10:   
      11:      return new RedirectResult(authorizationUrl);

    12: }

    AND

    public ActionResult CatchCode(string code)
    {
        AuthenticationContext ac = 
            new AuthenticationContext(string.Format("https://login.windows.net/{0}", 
                                      ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value));
        ClientCredential clcred = 
            new ClientCredential(AppPrincipalId, AppKey);
        var ar= 
            ac.AcquireTokenByAuthorizationCode(code, 
                       new Uri("https://localhost:44304/Home/CatchCode"), clcred);
        return View();
    }

    ----------------------------------------------

    When running both App and API (localhost) I log in once with my organizational account and when I access the WebApi by clicking on the About link I got redirected to login page but didn't have to login again as I was already logged in and got redirected to WebApp but this time it had the token to access the WebApi and the call succeeded.

    Everything went fine until the changes done to the WAAD.

    I am preparing to give a presentation at our organization on Single sign-on, OAuth, Common Consent Framework using WAAD and Visual Studio 2013 capabilities with Sharepoint online, and is scheduled on 13th March, which is a day away and due to these unwelcome changes just before the presentation:(, threw spanner in my work & planning. Now I am a bit apprehensive using Azure as I am not guaranteed with continuity of service.

    Let me know if you can help me out with achieving the same as before.


    • Edited by padraj Wednesday, March 12, 2014 9:37 AM
    Wednesday, March 12, 2014 9:37 AM
  • Yes, it worked after adding appPermission settings to the Manifest. 

    • Edited by Nirmalya Bharali Sunday, March 23, 2014 5:15 AM Removed old comments
    Wednesday, March 12, 2014 11:59 AM
  • Hi Padraj,

    Sorry about the change here.  We tested that existing (single tenant apps) with this configuration continue to work, without making any changes in the portal or in your app, so I'm surprised you are seeing this issue.  We were hoping to get some new documentation out for how to reconfigure your apps, if you wanted to see the set of permissions that your client app requires, given the consent framework changes and Azure Portal changes we made, but that's been delayed.

    Are you still hitting this issue?  Can you send us the error that AAD returns to your app or a fiddler trace so we can see what the problem is? 

    Can you confirm something for me...

    1.  When consenting to the web app, are you doing this with an org account from the same directory in which you registered the web app and web api applications?

    2. Is it possible that you exposed permission scopes (using the manifest on the web app rather than the web api)?

    3.  Were you consenting with a company administrator?

    Hopefully we can unblock you and get to the bottom of this.


    Dan Kershaw [msft]

    Wednesday, March 12, 2014 3:32 PM
  • Hi Nirmalya

    Can you provide some more details?  Can you paste the Manifest here?  I'd like to help to unblock you.

    Thanks,


    Dan Kershaw [msft]

    • Proposed as answer by padraj Wednesday, March 12, 2014 5:40 PM
    Wednesday, March 12, 2014 3:33 PM
  • Hi Dan,

    Thanks for your reply. First of all let me clear up things here.

    In my previous post I have written the situation about an existing app which I have registered in Azure portal before the recent changes have been made. This existing set of WebAPI and WebAPP are still working perfectly as before, so no problems there, I have just posted it so that it was clear to complete the story.

    After the upgrade to the Azure portal I have created for the presentation purpose in another Azure subscription account same set of Apps from VS 2013, but this time I could not relate the WebApi (provider) and WebApp (consumer of WebApi) as I did it earlier as the interface has completely changed.

    As you have suggested I have updated the WebAPI manifest and uploaded and (after reading the post of Nirmalya) I could select the WebApi through the drop-down and give permissions to the WebApp from the WebAPP interface.

    After this I have run both the applications in debug mode to test if the authorization works but I get a JSON message back:

    {"Message":"Authorization has been denied for this request."}

    Further to answer your questions:

    1) I use ORG account to log-in. The account is part of Office O365 Active directory tenant.

    2) I exposed permissions initially on WebAPI and when it didn't work then on WebAPP, but WebAPI seems to be the logical place.

    3) The Organizational account I am using to consent is indeed a Global Administrator of O365.

     I will post Fiddler output in a while.

    Here are the Fiddler request and response.

    Request:

    GET /api/Values HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:44312
    Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwczovL3Byb2plY3Rjb250cm9sLm9ubWljcm9zb2Z0LmNvbS9PQXV0aEFwaSIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2M5OWEyMWVmLTM5ZjktNGE1MS1iM2U5LWIzMTMyOThiNjkyOC8iLCJpYXQiOjEzOTQ2NDUzMDEsIm5iZiI6MTM5NDY0NTMwMSwiZXhwIjoxMzk0NjQ5MjAxLCJ2ZXIiOiIxLjAiLCJ0aWQiOiJjOTlhMjFlZi0zOWY5LTRhNTEtYjNlOS1iMzEzMjk4YjY5MjgiLCJvaWQiOiJiYWVlZDAyYi0yOTY5LTQ2YjEtYmJmZi1lODZkYTdlZGJjOWIiLCJ1cG4iOiJyYWpAcHJvamVjdGNvbnRyb2wub25taWNyb3NvZnQuY29tIiwidW5pcXVlX25hbWUiOiJyYWpAcHJvamVjdGNvbnRyb2wub25taWNyb3NvZnQuY29tIiwic3ViIjoiejFqZ2NxMjhhSlBucWRHeTQyMkU5TWppaTc2T1puOHdsQmRfd0V0QUlJZyIsImZhbWlseV9uYW1lIjoiSmFrc2FuaSIsImdpdmVuX25hbWUiOiJSYWoiLCJhcHBpZCI6ImRlNDlhZDZkLTFiOTMtNGMwZS1hMDFiLTkxZjBlZWQ2NWI4NCIsImFwcGlkYWNyIjoiMSIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsImFjciI6IjEifQ.WNdhT3g8SIXFSaaxou1pWC3yRXAqasnycPcuuJYKlhkiOMVv-uAvgZeMm4ax18Wd_qiYuOpFElDCNvs2HkVHKb7fWb1un02ykEgh7654zXqGMVtbnkuF6urMigRaI3jtctGp2bzxiEb9KzrIPJ2bvk6ottxD2rHSoTZtxEmbEFIoTKbf72aVoFkvz8tvafJb4CjxOoJsx7ZERj9VdZgPJsg9h48-981kizz1aMz7iLE7peIN9YbT2mu9wR2i966cbEqhiK9lhHD-yR8YUUkYgj-7HoLGV80faApinM54MbQkz74kYnWYL5HAwNg9GQ82rKkbUIKbFNVJONWv9LJaIg

    Response:

    HTTP/1.1 401 Unauthorized
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    WWW-Authenticate: Bearer
    X-SourceFiles: =?UTF-8?B?ZDpcdXNlcnNcamFrc2FucmFcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xPQXV0aEFQSVxPQXV0aEFQSVxhcGlcVmFsdWVz?=
    X-Powered-By: ASP.NET
    Date: Wed, 12 Mar 2014 17:36:40 GMT
    Content-Length: 61

    • Edited by padraj Wednesday, March 12, 2014 5:40 PM Added Fiddler output
    Wednesday, March 12, 2014 5:13 PM
  • Thanks. 

    If I read this correctly, it looks like you got an access token successfully to call your service, but that the service (your web API) is rejecting the request? 


    Dan Kershaw [msft]

    Wednesday, March 12, 2014 8:51 PM
  • That's true. Token is successfully received by the App but rejected by the service.

    Wednesday, March 12, 2014 9:41 PM
  • Have you remembered to update config in WebAPI, so it use the new client ids and so on?
    Wednesday, March 12, 2014 10:13 PM
  • I didn't update anything in the web.config as VS 2013 provisions everything from creating the entries in web.config to generating entries in the Azure portal.
    Wednesday, March 12, 2014 10:19 PM
  • Ahh of course, that's right. 
    Wednesday, March 12, 2014 10:22 PM
  • Have you tried to check through the code to where in the web API the token validation is failing and why this is resulting in an authorization failure?

    I've looked at your access/bearer JWT token and everything looks good in that token

    Are you sure your web API is configure with the correct audience and appIdUri?  I assume you are using this walkthrough/sample - http://msdn.microsoft.com/en-us/library/windowsazure/dn169448.aspx?

     

    Dan Kershaw [msft]

    Wednesday, March 12, 2014 10:32 PM
  • Hi Dan,

    I have double/triple checked all the variable stuff, seems to be good to me. Further I have followed blogs of Vittorio Bertocci.

    For the WebAPI: http://msdn.microsoft.com/en-us/magazine/dn463788.aspx

    and

    MVC WebApp: http://www.cloudidentity.com/blog/2013/10/29/using-adals-acquiretokenby-authorizationcode-to-call-a-web-api-from-a-web-app/

    Wednesday, March 12, 2014 10:46 PM
  • Can you post your web.config here too, so that we can double check it please?

    Thanks,


    Dan Kershaw [msft]

    Thursday, March 13, 2014 11:55 AM
  • WebApi Web.config

    -------------------------------

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      http://go.microsoft.com/fwlink/?LinkId=301879
      -->
    <configuration>
      <appSettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
        <add key="ida:Tenant" value="projectcontrol.onmicrosoft.com" />
        <add key="ida:Audience" value="https://projectcontrol.onmicrosoft.com/OAuthAPI" />
        <add key="ida:ClientID" value="b92cce59-b420-4afb-a4a5-04af24140501" />
        <add key="ida:Password" value="fmQGcbQkA2R62KbPDgqvEPv7ig0z6dCqoz69zsQbX68=" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.5.1" />
        <httpRuntime targetFramework="4.5.1" />
      </system.web>
      <system.webServer>
        <handlers>
          <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
          <remove name="OPTIONSVerbHandler" />
          <remove name="TRACEVerbHandler" />
          <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        </handlers>
      </system.webServer>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>


    Thursday, March 13, 2014 1:15 PM
  • WebApp web.config

    ----------------------------

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      http://go.microsoft.com/fwlink/?LinkId=301880
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      </configSections>
      <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-OAuthClient-20140310050721.mdf;Initial Catalog=aspnet-OAuthClient-20140310050721;Integrated Security=True" providerName="System.Data.SqlClient" />
      </connectionStrings>
      <appSettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
        <add key="ida:FederationMetadataLocation" value="https://login.windows.net/projectcontrol.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml" />
        <add key="ida:Realm" value="https://projectcontrol.onmicrosoft.com/OAuthClient" />
        <add key="ida:AudienceUri" value="https://projectcontrol.onmicrosoft.com/OAuthClient" />
        <add key="ida:ClientID" value="de49ad6d-1b93-4c0e-a01b-91f0eed65b84" />
        <add key="ida:Password" value="saQ9JEVyHKEKUFwqse7nV8akjW3GhbbSEwfuaCU4lUM=" />
        <add key="CallbackUri" value="https://localhost:44313/Home/GetResult"/>
        <add key="WebApiUri" value="https://localhost:44312"/>
      </appSettings>
      <location path="Account">
        <system.web>
          <authorization>
            <allow users="*" />
          </authorization>
        </system.web>
      </location>
      <system.web>
        <authentication mode="None" />
        <authorization>
          <deny users="?" />
        </authorization>
        <compilation debug="true" targetFramework="4.5.1" />
        <httpRuntime targetFramework="4.5.1" requestValidationMode="4.5" />
      </system.web>
      <system.identityModel>
        <identityConfiguration>
          <issuerNameRegistry type="OAuthClient.Utils.DatabaseIssuerNameRegistry, OAuthClient" />
          <audienceUris>
            <add value="https://projectcontrol.onmicrosoft.com/OAuthClient" />
          </audienceUris>
          <securityTokenHandlers>
            <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
            <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          </securityTokenHandlers>
          <certificateValidation certificateValidationMode="None" />
        </identityConfiguration>
      </system.identityModel>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v11.0" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
      <system.webServer>
        <modules>
          <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
          <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
        </modules>
      </system.webServer>
      <system.identityModel.services>
        <federationConfiguration>
          <cookieHandler requireSsl="true" />
          <wsFederation passiveRedirectEnabled="true" issuer="https://login.windows.net/projectcontrol.onmicrosoft.com/wsfed" realm="https://projectcontrol.onmicrosoft.com/OAuthClient" requireHttps="true" />
        </federationConfiguration>
      </system.identityModel.services>
    </configuration>

    Thursday, March 13, 2014 1:16 PM
  • WebApi Manifest contents:

    {
      "appId": "b92cce59-b420-4afb-a4a5-04af24140501",
      "appMetadata": null,
      "appPermissions": [
        {
          "claimValue": "user_impersonation",
          "description": "Allow the application full access to the OAuthWebApi service on behalf of the signed-in user",
          "directAccessGrantTypes": [],
          "displayName": "Full access to service",
          "impersonationAccessGrantTypes": [
            {
              "impersonated": "User",
              "impersonator": "Application"
            }
          ],
          "isDisabled": false,
          "origin": "Application",
          "permissionId": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",
          "resourceScopeType": "Personal",
          "userConsentDescription": "Allow the application full access to the WebApi service on your behalf",
          "userConsentDisplayName": "Full access to OAuthWebApi"
        }
      ],
      "availableToOtherTenants": false,
      "displayName": "OAuthAPI",
      "errorUrl": null,
      "homepage": "https://localhost:44312/",
      "identifierUris": [
        "https://projectcontrol.onmicrosoft.com/OAuthAPI"
      ],
      "keyCredentials": [],
      "logoutUrl": null,
      "passwordCredentials": [
        {
          "customKeyIdentifier": null,
          "endDate": "2015-03-10T15:57:17.6721265Z",
          "keyId": "128266e8-149f-4b36-ac66-b7d5ddb59ef1",
          "startDate": "2014-03-10T15:57:17.6721265Z",
          "value": null
        }
      ],
      "publicClient": null,
      "replyUrls": [
        "https://localhost:44312/"
      ],
      "requiredResourceAccess": [
        {
          "resourceAppId": "00000002-0000-0000-c000-000000000000",
          "requiredAppPermissions": [
            {
              "permissionId": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
              "directAccessGrant": true,
              "impersonationAccessGrants": [
                "User"
              ]
            },
            {
              "permissionId": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
              "directAccessGrant": true,
              "impersonationAccessGrants": [
                "User"
              ]
            }
          ]
        }
      ],
      "resourceApplicationSet": null,
      "samlMetadataUrl": null,
      "webApi": null,
      "webApp": false,
      "notifications": [],
      "objectType": "Application",
      "objectId": "2616a7f7-bf50-40f5-a2a1-91daa728031b",
      "softDeletionTimestamp": null,
      "createdOnBehalfOf": null,
      "createdObjects": [],
      "manager": null,
      "directReports": [],
      "members": [],
      "memberOf": [],
      "owners": [],
      "ownedObjects": []
    }

    Thursday, March 13, 2014 1:19 PM
  • I do see an issue with your web app configuration, but because you are getting what looks like a valid JWT token, I don't think this is the issue that is causing your web api to reject the API request. 

    However, I do see that you uploaded the appPermission to your web app (as well as your web API).  It's ONLY required on the web API.

    To remove appPermissions is a little more involved since you need to first disable a permission before you can remove it.  For now I think we can we can leave it (because I don't believe it impacts anything or that it's the root cause here), but until you make the change, your OauthClient will show up in the list of applications/web APIs that other clients can access.

    I can't see anything obviously wrong with your web config for your web API, assuming that you are using OWIN and Vittorio's blog to configure your web API to accept OAuth tokens from your client.  I'll see if Vittorio might be able to help...

     

    Dan Kershaw [msft]

    Thursday, March 13, 2014 3:39 PM
  • Everything working fine. I have created two new solutions and went through the process all over and things are working now. It's still a mystery why the earlier application had issues at different stages. I attribute the success to a probable update to the Active directory add-on within the Azure portal. When working in the portal a message got displayed that the Azure Portal got an upgrade.

    Thanks anew.

    Raj

    Thursday, March 13, 2014 8:59 PM
  • That's great to know. Vittorio and I were scratching our heads as to why this wasn't working...

    Thanks for letting us know.


    Dan Kershaw [msft]

    Thursday, March 13, 2014 9:15 PM
  • I have the same problem. Actually, when I followed tutorials at http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf, it worked days before but not any more. I always get the same error saying "The system cannot locate the resource specified". 
    Friday, March 14, 2014 6:34 AM
  • Thanks for this short sample Dan, it got my code to work again. Just one weird thing - when I uploaded the updated manifest for the web api, the management portal gave me en error message that the upload failed (several times). But when I downloaded the manifest it had the new parts in it, and the application was visible to the app in the dropdown, so I selected it, and tried my client code and it worked!

    Is it too much to hope for a graphcial interface to this manifest? ;)

    I wish I could have an email the next time these things change. I know it's preview, but still :)

    Thanks again!


    /Johan

    Wednesday, March 19, 2014 1:02 PM
  • And today it doesn't work... this is getting frustrating :( 

    The api is shown in the dropdown list for the client, I've selected it, and checked the permission and saved. When I run the client I get the login dialog, but the rest api returns a Authorization has been denied for this request.


    /Johan

    Thursday, March 20, 2014 9:14 AM
  • Sorry to see you hit this, and that it's causing you some frustration

    Not sure what has changed that would cause this problem.  Are you sure you didn't make any changes to the client or web API/service? 

    If not, there seems to be some systemic problem here.  Are you able to debug this on the web API side to see why the failure is occurring now?  Are you getting the access token, are you able to view the access token claims on the web API side, is the token correctly validated etc?


    Dan Kershaw [msft]

    Thursday, March 20, 2014 6:16 PM
  • Dan I'm not sure where to start... I decided to do it right from start again and I get the same error - Authorization has been denied for this request. I'm thinking I'm doing something basically wrong. I'll try do describe the steps, and hopefully you can catch the error.

    * I create a new web site in Azure

    * I create a new ASP.NET Web API project

    * I Change the Authentication to Organizational Accounts, update to our domain name, and ask for Read directory data Access Level

    * Back in Visual Studio 2013 I select to Publish... then Import the publishing profile for the newly created web site

    * I can test the /api/values api with Fiddler, and it works well

    * I add the [Authorize] attribute to the ValuesController, upload and try again - no it fails with HTTP/1.1 401 Unauthorized, as it should

    * Now I go back to Azure portal and download the manifest for the web site, then replace the appPermissions value with this:

       "appPermissions":[
          {
             "claimValue":"user_impersonation",
             "description":"Allow the application full access to the service on behalf of the signed-in user",
             "directAccessGrantTypes":[
    
             ],
             "displayName":"Have full access to the service",
             "impersonationAccessGrantTypes":[
                {
                   "impersonated":"User",
                   "impersonator":"Application"
                }
             ],
             "isDisabled":false,
             "origin":"Application",
             "permissionId":"b69ee3c9-c40d-4f2a-ac80-961cd1534e40",
             "resourceScopeType":"Personal",
             "userConsentDescription":"Allow the application full access to the service on your behalf",
             "userConsentDisplayName":"Have full access to the service"
          }
       ],
    

    * I upload the updated manifest, but get an error from the portal saying: "Failed to upload manifest for "Webapp-johan-test-api..." and so on. If I download the manifest I can see the the updated appPermissions, so the upload seems to work. But seeing an error message is never good...

    * Now I go to the Active Directory section in the portal and select to add a new application - "Add an application my organization is developing" and I name it "johantestapiclient" and select "Native client application" because I will create a WPF application to test this web api. The redirect uri I set to "http://johantestapiclient"

    * Then I go to the "configure" section of the newly created client and down at the bottom under the "permissions to other applications" I can now see and add my web api, so I guess something was right with the manifest despite the error? I select and check the delegated permission for the api and save.

    * Finally I create a new WPF project, install the ADAL prerelease packet from Nuget (version 2.5.1-alpha prerelease) and add this simple code to the code behind of the main window:

     private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
            {
                // Get token
                var ac = new AuthenticationContext("https://login.windows.net/irm.se"); //ad domain = irm.se
    
                var ar1 = ac.AcquireToken("https://irm.se/WebApp-johan-test-api.azurewebsites.net",    //resource id of the web api
                  "3e1c948a-9158-47c7-8bd5-71f7447ac4b0",   //the client id
                  new Uri("http://johantestapiclient"));    //the client redirect uri
    
                // Call Web API
                var authHeader = ar1.CreateAuthorizationHeader();
                var client = new HttpClient();
                var request = new HttpRequestMessage(HttpMethod.Get, "http://johantestapi.azurewebsites.net/api/values");
                request.Headers.TryAddWithoutValidation("Authorization", authHeader);
                var response = await client.SendAsync(request);
                var responseString = await response.Content.ReadAsStringAsync();
                MessageBox.Show(responseString);
            }

    That's it. When I run the code, I get the login dialog and the call is made, but fails with the error message above.

    Hope this helps, I'm sure I'm doing something wrong, perhaps with the manifest file. I've validated the json, and it is "correct json". May it have something to do with me asking for Read directory data Access Level? I've not tried without it.

    Also, I'm not sure at all how to debug the server side. There is no visible authentication code to debug in a vanilla ASP.NET Web API project! :D

    I get a proper token and so on.. It looks like this: 

    Bearer eyJ0eXAiOiJKV1QiLCJhbGc... and so on

    Cheers for any help!

    Johan


    /Johan

    Thursday, March 20, 2014 9:32 PM
  • Sorry Johan.  I can't see anything obviously wrong here.

    I assume that "https://irm.se/WebApp-johan-test-api.azurewebsites.net" is what is set in the web API's  "ida:Audience" in its web.config?

    Can you send the full bearer token (or base 64 decode it to check what the aud claim is set to please?)


    Dan Kershaw [msft]

    Saturday, March 22, 2014 1:29 AM
  • Hi Dan I'm having the exactly same problem as Johan is. I'm not even retyping the sample here because it's the exact same thing.

    Thanks,

    Gabriel

    Saturday, March 22, 2014 2:27 PM
  • Dan, I deleted the code and started all over again. This time the upload of the manifest didn't give me any errors so I thought things would work out better, but no. A new error happened in the portal - the newly created web api project never showed up in the ad/application list. Both the localhost-project and the WebApp-xxx application was missing. I tried to move out and back again but it didn't help so I created the web app myself, but I still got the same "Authorization has been denied for this request" mesage.

    Then I logged out of the portal, and logged in again and now the applications show up again... with "duplicates" on the names from the ones I created myself. Anyway, I'll delete them all and start all over again :)

    brb...


    /Johan

    Saturday, March 22, 2014 8:03 PM
  • Well I finally got things to work - both against the web api project on localhost, AND on the azure server! I started all over again and this time when I uploaded the manifest(s) I got the upload error again (you have to look at this please...). Anyway, for localhost I made sure the values for audience and client-id in the web.config file was the same as in the portal, then I made sure the app id uri in the call to AcquireToken() was the same as the audience value, and IT WORKED! :)

    Next I updated web.config with the values of the azure application, and also changed the resource/app id in the call to AcquireToken() and it worked! Phew! I think the audience/app/resource and client id's must have been messed up!

    I'll try to write a detailed blog post about the steps and what to think about.

    Phew... :)


    /Johan

    Saturday, March 22, 2014 8:38 PM
  • I've written a loooooooooong walkthrough with all the steps to do this, against localhost and also with publishing to an azure web site and some sample WPF client code to access it. Hope it helps. I'd love to get feedback if I've done something wrong or unnecessary!

    http://weblogs.asp.net/jdanforth/archive/2014/03/23/secure-asp-net-web-api-with-windows-azure-ad.aspx

    Cheers,

    Johan


    /Johan

    Sunday, March 23, 2014 7:30 PM
  • Wanted to let folks know that now whenever you create a web app/api application through Visual Studio, Graph API or the Azure Management Portal, the platform will always create a default oauth2Permission (was appPermission) for you.  So you no longer need to download the manifest, update the manifest to expose a permission, and upload the manifest.  Your newly created application should be "automatically" visible to other client applications when using the "Permissions to other applications" section in the app configuration page.

    Dan Kershaw [msft]

    Tuesday, December 23, 2014 1:41 AM
  • Hi:

    i have a question about the "Permissions to other applications" section in the app configuration page.

    In  "Permissions to other applications" section there have no "Exchange Online" and "Sharepoint online" available for selection.

    I didn't know why, my Azure account also have office365 subscription.

    would you help me?

    Thanks.

    Thursday, December 25, 2014 2:05 AM
  • Wanted to let folks know that now whenever you create a web app/api application through Visual Studio, Graph API or the Azure Management Portal, the platform will always create a default oauth2Permission (was appPermission) for you.  So you no longer need to download the manifest, update the manifest to expose a permission, and upload the manifest.  Your newly created application should be "automatically" visible to other client applications when using the "Permissions to other applications" section in the app configuration page.

    Dan Kershaw [msft]


    Hi:

    i have a question about the "Permissions to other applications" section in the app configuration page.

    In  "Permissions to other applications" section there have no "Exchange Online" and "Sharepoint online" available for selection.

    I didn't know why, my Azure account also have office365 subscription.

    would you help me?

    Thanks.

    Thursday, December 25, 2014 2:05 AM
  • Wanted to let folks know that now whenever you create a web app/api application through Visual Studio, Graph API or the Azure Management Portal, the platform will always create a default oauth2Permission (was appPermission) for you.  So you no longer need to download the manifest, update the manifest to expose a permission, and upload the manifest.  Your newly created application should be "automatically" visible to other client applications when using the "Permissions to other applications" section in the app configuration page.


    Dan Kershaw [msft]


    Hi:

    i have a question about the "Permissions to other applications" section in the app configuration page.

    In  "Permissions to other applications" section there have no "Exchange Online" and "Sharepoint online" available for selection.

    I didn't know why, my Azure account also have office365 subscription.

    would you help me?

    Thanks.

    this problem is solved.

    the solution is:

    1.click "Add application".

    2.select "other" on the Comobox.

    3.click right-top button to search. the office365 applications will be showed in the list.

    Monday, December 29, 2014 1:51 AM