HTTP Authentication¶
This recipe uses App Service Authentication (Easy Auth) with Java HTTP triggers, where authentication is enforced at the platform layer and identity claims are passed in request headers.
Architecture¶
flowchart LR
CLIENT[Client with Microsoft Entra sign-in] --> EASYAUTH[Easy Auth on Function App]
EASYAUTH --> FUNC[HTTP Trigger authLevel=ANONYMOUS]
FUNC --> CLAIMS[Read Easy Auth identity headers]
CLAIMS --> API[Authorization logic] Prerequisites¶
Use AuthorizationLevel.ANONYMOUS in code and enable authentication in the platform:
az webapp auth update \
--resource-group $RG \
--name $APP_NAME \
--enabled true \
--action LoginWithAzureActiveDirectory
Set unauthenticated behavior to require sign-in:
az resource update \
--resource-group $RG \
--name $APP_NAME/authsettingsV2 \
--resource-type "Microsoft.Web/sites/config" \
--set properties.globalValidation.unauthenticatedClientAction=RedirectToLoginPage
Java implementation¶
package com.contoso.functions;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import java.util.Map;
import java.util.Optional;
public class EasyAuthFunction {
@FunctionName("profile")
public HttpResponseMessage run(
@HttpTrigger(
name = "request",
methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.ANONYMOUS,
route = "profile"
) HttpRequestMessage<Optional<String>> request
) {
String userId = request.getHeaders().get("x-ms-client-principal-id");
String identityProvider = request.getHeaders().get("x-ms-client-principal-idp");
String displayName = request.getHeaders().getOrDefault("x-ms-client-principal-name", "unknown");
if (userId == null || userId.isBlank() || identityProvider == null || identityProvider.isBlank()) {
return request.createResponseBuilder(HttpStatus.UNAUTHORIZED)
.body(Map.of("error", "Missing Easy Auth identity headers"))
.build();
}
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body(Map.of(
"userId", userId,
"identityProvider", identityProvider,
"displayName", displayName,
"message", "Authenticated by Easy Auth"
))
.build();
}
}
Implementation notes¶
- Keep trigger auth at
ANONYMOUSwhen Easy Auth is the enforcement point. - Trust identity only when the request came through App Service Authentication.
- Read identity from
x-ms-client-principal-id,x-ms-client-principal-idp, and optionalx-ms-client-principal-nameheaders. - Add role checks only when endpoint-level authorization decisions are required.