mspnp / AzureNamingTool

The Azure Naming Tool is a .NET 8 Blazor application, with a RESTful API. The UI consists of several pages to allow the configuration and generation of Azure Resource names. The API provides a programmatic interface for the functionality.
https://aka.ms/azurenamingtool
MIT License
308 stars 604 forks source link

API does not work with Azure App Service Authentication enabled #32

Closed ArlanNugara closed 7 months ago

ArlanNugara commented 8 months ago

Describe the bug The API does not authenticate with API Keys when Azure App Service Authentication is enabled.

To Reproduce Steps to reproduce the behavior:

  1. Enable App Service Authentication in Azure
  2. Restart the App Service
  3. Try calling API using curl / python or any tool

Expected behavior Json response with name and status code.

Additional context The API works perfectly fine when Azure App Service Authentication is disabled.

BryanSoltis commented 8 months ago

Hi @ArlanNugara,

Thank you for your feedback. When using Azure AD Authentication for the App Service, you have to set OAuth 2 authentication in order to access the API. There are lots of ways to do this, depending on how you are calling the API. This is not specific to the Naming Tool, btu rather OAuth 2.0.

The overall process:

As an example, here is a good guide on accessing an Azure AD-protected API using Postman. The guide is good, but has a very areas that are may be a little confusing. I've tried to clarify this below.

https://dev.to/425show/calling-an-azure-ad-secured-api-with-postman-22co

For the guide, a few tips to help you get going:

Here is a working example:

image

HJopefully this helps you get started with the API and OAuth 2.0.

ArlanNugara commented 8 months ago

@BryanSoltis I am going to try this out now.

ArlanNugara commented 8 months ago

@BryanSoltis I am trying a small python script to get names. I am able to get Bearer Token from Azure. However, it's not working when passing the Token to Naming Tool API. The error is as follows : -

{'code': 401, 'message': "IDX10214: Audience validation failed. Audiences: 'https://management.azure.com/'. Did not match: validationParameters.ValidAudience: 'XXXX-XXXX' or validationParameters.ValidAudiences: 'api://XXXX-XXXX-XXXX'."}

The code is as follows -

import json
import os
import requests

# Login and get access token
LOGIN_URL = "https://login.microsoftonline.com/"+os.environ.get('ARM_TENANT_ID')+"/oauth2/token"
PARAMS_MGMT = {'grant_type':'client_credentials','client_id': ''+os.environ.get('ARM_CLIENT_ID')+'','client_secret':''+os.environ.get('ARM_CLIENT_SECRET')+'', 'resource':'https://management.azure.com/'}
login = requests.post(url = LOGIN_URL, data = PARAMS_MGMT)
jsonfy = login.json()
token = jsonfy["access_token"]
query_header = {"Content-Type": "application/json", "accept": "*/*", "Authorization": "Bearer "+token}
print("Login Successful")

# Payload
json_data = {
    "resourceEnvironment": ""+os.environ.get('ENVIRONMENT')+"",
    "resourceFunction": ""+os.environ.get('FUNCTION')+"",
    "resourceInstance": "001",
    "resourceLocation": ""+os.environ.get('LOCATION')+"",
    "resourceOrg": ""+os.environ.get('ORGANIZATION')+"",
    "resourceProjAppSvc": ""+os.environ.get('PROJECT')+"",
    "resourceType": "st"
}

# Get Names
URL = os.environ.get('API_URL')
get_names = requests.post(url = URL, headers = query_header, data = json.dumps(json_data))
get_names_json = get_names.json()
print(get_names_json)
BryanSoltis commented 8 months ago

You probably need to supply the scope, as well. You can find it in your App Registration (for the tool) / Expose an API:

image

-Bryan

ArlanNugara commented 8 months ago

@BryanSoltis The error remains same with scope and without scope. Also tried with "api://" and without "api://" in scope.

BryanSoltis commented 7 months ago

Hi @ArlanNugara ,

I suspect it's something related to your implementation of OAuth 2.0 and Azure AD. The tool itself does not have any code that enables/implements the authentication. If Authentication is implemented (Example: Enabling Authentication on the Azure App Service), this will inject headers into the request (for the user information). The tool looks for these headers and, if they are present, identifies the user/admin. I was able to get it working using Postman, but that required some very specific Azure AD App Registration.

I would recommend continuing to work on your OAuth 2.0 implementation and how Azure AD implement this. This link may provide some additional guidance:

https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols

-Bryan

BryanSoltis commented 7 months ago

Closed due to inactivity.