4

I have a regular ASP .NET Web Application that I deployed into Azure using App Services. After I deployed it, I enabled the App Service Authentication and configured Azure Active Directory. That allowed me to publish my Web Application and also have authentication so only people who are part of the Active Directory can log in.

enter image description here

On the other hand, I deployed an ASP .NET Web API as a Cloud Service. The Web Application is supposed to load some information calling the Web API (which loads some data from a SQL Database and return it back) and then displaying the information back in the UI. However, when I call the API, the Azure Active Directory credentials doesn't get passed from the Web App to the Web API.

Below is some code that I have in the Web Application that calls the Web API endpoint.

public string GetStringAsync(string endPoint)
{
    HttpClientHandler handler = new HttpClientHandler
    {
        UseDefaultCredentials = true
    };
    handler.PreAuthenticate = true;
    using (HttpClient client = new HttpClient(handler))
    {
        return client.GetStringAsync(endPoint).Result;
    }
}

But when I try to get the username when the call goes to the API, I get an empty string. Below is what I do to capture the Identity of who called the API:

HttpContext.Current.User.Identity.Name;

How can I get the Azure Active Directory domain\user information at the time the Web Application calls the Web API? Possibly my function to call the API is completely wrong?

user3587624
  • 1,427
  • 5
  • 29
  • 60
  • Your web app should get an access token for the API from Azure AD and attach it as a request header for the HTTP call. – juunas Jul 11 '17 at 14:06

3 Answers3

2

Based on the description, you deploy the web app on Azure and protecting the web app using Azure AD.

AFAIK, in this scenario, it is not possible to pass the credential to the web API. The corresponding solution, you should protect the web API using Azure AD (we can use the same app which protect the web app)and get the access_token for the web API. Then the web APP can call the web API using the access_token.

To config easy auth to get the token for the web API, you can refer this blog(Step 2: Update App Service Auth Configuration via REST API) and replace the resource value with APP ID of the app which you protect the web API. And to get the access_token from web app, you can follow Calling the Graph API as the End-User section of that blog.

Fei Xue
  • 14,369
  • 1
  • 19
  • 27
  • So you are saying there is no possible way for me to know the domain/user who is calling the API? The API needs that information later on to provide customize content based on the domain/user – user3587624 Jul 12 '17 at 21:37
  • You are not able to pass the credentials. But you were able to get know the user if the web API is protected by the AAD. You can decode the token get the current user info. More detail about this scenario, you can refer web application calling web API from [this document](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#web-application-to-web-api). – Fei Xue Jul 13 '17 at 08:48
  • How can I get the Token that got created when the user signed in on the Web Application that calls the Web API? this.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"]; returns something that doesn't look like a Bearer token. Also, even if I generate one at runtime using the app Id and secret, when I call the web API, I can't retrieve the user name, domain/name or any other similar information at all. The only way I found is to pass the email address from the web app to the web API as part of the http request but I don't think this is right at all. – user3587624 Jul 27 '17 at 06:46
  • 1
    A more easy way for this scenario is using the OWIN component both in the web app and web API. And in this scenario, there is no need to enable the easy auth for the web app. You can refer the code sample [here](https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect) about this scenario. – Fei Xue Jul 27 '17 at 07:50
0

1- Read the .ASPX auth cookie from the web app

HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
string authToken = authCookie.Value;

2- Set the cookie into httpclient. cookie value must have same .ASPX auth cookie.

How do I set a cookie on HttpClient's HttpRequestMessage

3- read username from web api with HttpContext.Current.User.Identity.Name.

Hope this helps.

Houssam Hamdan
  • 888
  • 6
  • 15
  • Could you provide some documentation or code examples for the first two steps you described? – user3587624 Jul 11 '17 at 06:28
  • Actually I can't doo Request.Cookies. Apparently the type name Cookies doesn't exist. – user3587624 Jul 12 '17 at 21:36
  • you must read the cookie on mvc action not wcf or you mean wcf service does not rely on request cookie for authentication ? i mentioned cookie for windows authentication to work. I believe i did not understand your question well. – Houssam Hamdan Jul 14 '17 at 07:09
0
[Authorize]
public IEnumerable<Object> Get()
{
 var owner = ObtainCurrentOwner();
 var assets = GetAssets(owner.Id);
 return result;
}

protected Owner ObtainCurrentOwner()
{
 return RavenSession.Query<Owner>().SingleOrDefault(x => 
           x.UserName == HttpContext.Current.User.Identity.Name);
}

public IEnumerable<Asset> GetAssets(int ownerID)
{
 return RavenSession.Query<Asset>().Where(x => x.OwnerId == ownerID);
}

This method is decorated with the [Authorize] attribute. This mechanism was known previously in WCF. ASP.NET checks for the cookie within this request and if no cookie is present the request is rejected. Getting the current user and all its assets is a matter of two LINQ queries using the RavenSession which has to be opened before.

https://www.codeproject.com/Articles/568115/Sample-application-RavenDB-KnockoutJS-Bootstrap-We

vaquar khan
  • 10,864
  • 5
  • 72
  • 96