Azure AD authentication in published WebAPI not working - azure

I am trying to add Azure Active Directory authentication to my ASP.NET WebAPI.
I followed this tutorial and have configured my tenant and applications in Azure correctly.
Now if I test this locally with a sample desktop client, the authentication works and I can see the authenticated user's claims.
User.Identity.IsAuthenticated = true
However, if I publish my API to Azure (as a Web app), the authentication does not seem to be working anymore, even with the exact same code used to test the API locally... The only this I have to change is the endpoint to my API:
<add key="ApiBaseAddress" value="http://localhost:20105/" />
vs
<add key="ApiBaseAddress" value="https://***.azurewebsites.net/" />
Note that the JWT token passed to the API is exactly the same when testing my API locally and published, as they are authenticating to the same Azure AD and the same user accound.
What could be the source of this problem?
Could it be that azure uses https and I am running on http locally? If so, what could I try to fix this issue?

It seems that when publishing to Azure, some of my Azure AD specific config values in my web.config were replaced...
If you Enable Organizational Authentication, you are able to choose an existing AD, but the deployment just added the config values in a different way than I did.
Unchecking this option and taking care of it myself solved the issue

This might be due to the process you follow for publishing your API. If you are publishing from Visual Studio and you are using the "organizational" settings, the publishing logic will create a NEW app in Azure AD for your cloud hosted web API instance and change the audience settings accordingly. As such, you need to match those changes in the logic requesting a token as well - you need to request a token for your API using the same audience as resource identifier or you'll end up getting a token for your localhost based deployment and send it to your cloud instance, which will reject it.
You can avoid this by opting out of using the organizational settings when publishing your app to the website - that will keep the audience unchanged and allow you to use tokens against local and cloud instances indifferently.

Related

Azure DevOps Web Extension : OAuth2 Authentication (Authorization code) to request custom API in Azure

We developed an API hosted in Azure and we decided to experiment a frontend in Azure DevOps with a web extension in react.
Without authentication, it worked :D
So, let's move on OAuth2.
In the past we developed task extensions with custom service connections. So we decide to experiment them with the acceptance criteria of an authentication based on AzureAD (or related to as Azure DevOps) with userId in claims in API scope and keep benefit of Azure DevOps not to ask a second authentication to users. (no MSAL for now....)
Simple first solution was to use core sdk getAppToken function. But token was not containing userId information.
We them tried service connections :
Client credentials
Native azurerm service connection works but with some limitation. We can't use a datasourcebinding with datasourceurl as it should begin with {{config.url}} or {{endpoint.url}}. And endpoint.url is "https://management.azure.com", so we can't call our api :
We also tried to use managed service identity service connection type (ms.vss-endpoint.endpoint-auth-scheme-managed-service-identity for curious). Because in task extension frontend, Azure DevOps is using user credentials to request Azure for any datasourcebinding.
But Microsoft seems to block this kind of authentication to their type azurerm :
Let's now try OAuth2 configuration :
So we created a custom service connection and defined authentication and datasource like ServiceNow endpoint :
https://github.com/Microsoft/azure-pipelines-extensions/blob/master/Extensions/ServiceNow/Src/vss-extension.json
OAuth2 configuration url : https://login.microsoftonline.com/XXX/oauth2/v2.0
AuthorizationUrl : {{{configuration.Url}}}/authorize?client_id={{{configuration.ClientId}}}&response_type=code&redirect_uri={{{RedirectUrl}}}&scope=api://XXX/.default
AccessToken and RefreshToken datasourcebindings requestUrl {{{configuration.Url}}}/token"
Everything was in place to use a configuration.url for code and token. Whereas endpoint.url was pointing to our API in Azure with a custom domain.
But it failed because I realized when a code is requested through service connection of kind OAuth2, serverurl is magically replaced by configurationUrl...
I didn't understand this issue with executeServiceEndpointRequest function call :
Backend code is inspired from mkaszub post : https://github.com/microsoft/azure-devops-extension-api/issues/12
It comes before real request and after service connection get.
The strangiest thing is that next call to API itself failed but not because or bad url. First endpoint.url at service connection creating was still there...
Conclusion, fail to use OAuth2 configuration in Azure DevOps with an Azure API.
So, do you know how to call an API inside Azure DevOps web extension with a user generated AzureAD token ?
Solution we think of :
MSAL should be the way to go for standard authentication, but we will need to ask for user to login. Even he's already inside Azure DevOps. Any trick to avoid this ?
MSAL with frontend outside Azure DevOps, inside Azure. But we loose Azure DevOps integration. And using extension with hub collection, would brings unique API frontend places.
Anyway, Thank you for time you spent reading me.

Azure App Service Authentication with Active Directory

I have a dotnet core api in an app service on Azure.
When I run this locally, with authentication switched on, I can generate a bearer token and use that to successfully access the end points.
On azure, when authentication is switched off I can access the end points, but when I switch authentication on in azure, I can't access any end points with a token. Postman is just returning the standard response "The page cannot be displayed because an internal server error has occurred".
I can't see anything in application insights so I'm really in the dark.
Hoping someone will know of any common issues that could be behind this.
Thanks in advance
You cannot access your web app authenticated with Azure AD using B2C token.
On local, created web app using Visual Studio only have three authentication choices:
As we can see, using Individual User Account is connecting to an Azure AD B2C account.
On portal, you could configure your app service with choices below:
If you are using Log in with Azure Active Directory, you should concern it is not same as B2C. Follow this page to configure Azure AD authentication with web app.
Get the AAD bear token:
Navigate to the app registrations page in your Azure Active Directory, choose the one you created in configuring authentication step. You would see the information like this:
Go to Certificates & secrets page to create a secret, and copy that value, cause you would not see it after leave this page.
Open Postman to get the access token, here is the required parameters:
Use the bear token you got from last step to access your web app:

Azure AD Multi tenant app

I have added a Web Application in the Microsoft Application Registration Portal. I can view this app in old azure portal. When I try to configure this app as multi tenant and set the Sign-on URL and the App ID URI values, an error pops up saying one of the values is invalid and the save fails. I can connect to this application using OAUTH and get the required refresh and access tokens. Using these tokens in the graph API I can get mails,contacts and calendar events from my office 365 account. But this happens only for a single tenant. I need to able to do this for multiple tenants and so I want to set this app as multi-tenant. If I create the application in Azure AD itself then I am able to set all the values but I cannot connect to this app using OAUTH as the authentication fails with error message saying
error=unauthorized_client&error_description=AADSTS70001%3a+Application+%2791470123-7e7e-4139-9922-ac95b0a6b383%27+is+not+supported+for+this+API+version.
.I went through a few links like here , here and here but until now I haven't been able to find a solution. I am re-posting this as suggested here. Can anyone suggest what I must do to get through this ?
All applications created through the App Registration Portal have the Multi-Tenant flag set to True by default.
The issues you are facing here are likely due to the fact that the App Registration Portal created our new V2 Applications, while our old portals use our V1 Applications. As a result, switching between portals and trying to make configuration changes, you will likely run into issues where our app model has changed, and certain properties exist in one place, and not another.
Finally it is important to note that we now have a V2 endpoint as well, which lines up with our V2 applications. You need to make sure you are using the right kind of application for the right endpoint.
Let me know if this helps!

Authentication for web api using azure AD

I need to implement authentication for azure web api using azure active directory.
client app(which consumes webapi) may or may not be in azure. how i need to authenticate user, where i should generate token if my app is not in azure(if it is IOS app). authentication should work in all cases even if client app is in azure or not.
Please let me now the best procedure to implement authentication.
You need to define the client app in Azure AD as a native app in the case of a mobile app. Then you define the API there, and add your client permissions to access it. You can optionally customize the available permissions through the API app's manifest in Azure AD. Then when your mobile app opens, you would have to authenticate with Azure AD, and then request an access token for the API. That you can then use to authenticate requests.
I can't answer this question in too great detail because it is quite a large topic and how it is done also depends on your platform. There is a sample app that you can check which does exactly what you want. The whole list of examples for native apps can be found here.
App Service to use different authentication providers Azure Active Directory,Facebook,Google,Microsoft,Twitter.
We can set any type of Authentication/Authorization in the Azure Portal.More info about how to use authentication for API Apps in Azure App Service, please refer to document.
By default, App Service provides authentication but does not restrict authorized access to your site content and APIs. You must authorize users in your app code.

Azure WCF Service with Azure Active Directory Authentication

I know this question seems similar to other son here, but I have tried the answers posted Here: Securing WCF 4.5 service using Azure ACS 2.0
And Here: Federated authentication (single-sign-on) for a WCF REST/HTML-service on Azure
Ans neither seem to be relevant.
Here is what I have so far.
An azure cloud service with various worker roles, and a WCF web role with REST and SOAP Endpoints
An azure active directory account with a couple users
ACS namespace.
The WCF service will be used by a couple different companies but other than that closed off. We chose azure active directory to provide SSO for the wcf service and other apps.
Here is what I want to do:
Create users/passwords for each company using the WCF service in
Azure Active Directory.
Allow only companies with a valid username and password pair to obtain an access token
Have each company use their token to access the WCF methods.
I didn't think this would be that hard to accomplish, but all the tutorials out there seem to be for IIS hosted or self hosted services with a console application.
What I have done so far:
Added the WCF service as an integrated app in azure active directory
Created a new identity provider named testAAD in ACS and added the WS-Federation metadata from the integrated app to that provider
Added a relying party application that uses the newly created testAAD identity provider
Added a rule group with a pass-through rule that uses the testAAD Identity Provider and the default settings.
See option 1 here for more details.
I need to know if what I did was anywhere close to correct, and if it was, how do I get the WCFservice to start using those settings.
Other Info:
WIF 4.5
VS2012 Pro
C#
Any relevant tutorial links or general advice would be great. Thanks in advance.
Update:
Just to add more info, the WCF service is being posted to by a number of different websites. Each of our customers will collect data from their own web forms, and then either add a service reference using c# code, or post the data to a url via something like curl if they are using php. The Service has both rest and soap endpoints. So for example, they would send an XML or SOAP request to mynamespace.cloudapp.net/myservice.svc/servicemethod. I am either looking to have them send their username and password with that request and validate those credentials in the actual WCF Method, or have them request an authentication token, and then send that authentication token with their request.
Update 2
I think I found the missing piece. In order to use active directory as an identity provider, it looks like I need to set up an ADFS server. I had thought that the ADFS server was set up already with the azure active directory account, but apparently thats not the case? Is there any way to do this without an ADFS server?
The main question you haven't covered is how will these companies use that WCF service?. Via your web portal, or via rich client (such as WinForms / WPF)?
If it is rich client, you can take a look at this blog post? It shows you how to secure WCF service with token and access that service from a WPF application.
If you plan to only allow access to the WCF service via your web portal, then picture is a bit different. You can first protect your portal by Azure AD and get user's token. Then use that token to authenticate against the WCF.
But in a truly web scenario, the client that will make calls to the service is actually your web server. If this is the case, I will just protect my web portal with Azure AD. Then protect my WCF with a single access token. I can get that token from a Service Identity in my Azure AD Access Control. And provide this "Service Token" as part of each WCF call from my web server. For added audit (and compliance) I will also send the original user token, to keep track of who accessed what and when.

Resources