I successfully set up a sample application to utilize AzureAD for user authentication following the steps outlined in this blog post. The post provides instructions on configuring AzureAD and the application’s identity using client-id and client-secret for the application configuration, and the setup working properly.
However I try to configure AzureAD and application’s identity using with public key I could not able to successfully setup.
I used following openssl commands to generate the public key.
$certname = "AzureCertificate"
$cert = New-SelfSignedCertificate -Subject "CN=$certname"
-CertStoreLocation "Cert:CurrentUserMy" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256Export-Certificate -Cert $cert -FilePath
"C:PersonalWork1AZUREKEY$certname.cer"
Then I generated the public key using following command in command line
openssl x509 -inform der -in AzureCertificate.cer -pubkey -noout >
your-public-key.pem
Then I uploaded the generated certificate AzureCertificate.cer file in to the AzurePortal application as show below.
Then I have configured the certificate location on the applciation.yml as show below and added publicKey.pem file in to resources folder. Please note I have replace correct my-tenant-id and my-client-id in applciation.yml file.
Then I have run the application It first correctly redirecting to Microsoft login page and then after user enters the credentials system giving error message as below.
[invalid_request] AADSTS900144: The request body must contain the following parameter: ‘client_id’. Trace ID: yyyyyyy Correlation ID: xxxxxxx Timestamp: 2023-11-18 15:14:37ZHighly appreciated if someone share your experiencing this configuration process.
3
Answers
You have followed the steps to generate a certificate, uploaded it to Azure, and configured your
application.yml
with the public key, but you are receiving an error stating that the ‘client_id’ parameter is missing.From the error message in the last screenshot, it seems that the AzureAD authentication process is not receiving the
client_id
parameter as part of the request, as in this question or this one.From your
application.yml
, I have a few suggestions:The
provider
underregistration
should match the name of the provider underprovider
. In your configuration, the provider is namedazure
in both sections, which is correct. But make sure this consistency is maintained throughout the application.The scopes specified under
registration
are typically correct for OpenID Connect (openid
,email
,profile
). Check that the scopes align with what your application requires and what Azure AD is configured to allow.The
jwt.key-set-uri
underprovider
should be unnecessary in the context of client authentication usingprivate_key_jwt
. That setting is typically used by resource servers to validate JWTs, not by clients to authenticate to the authorization server.If using
private_key_jwt
for authentication, theclient-secret
should not be present, as this authentication method uses a private key instead of a client secret. (as confirmed in "How to Get an Azure Access Token Using Self-signed Certificate with Spring Boot" from Milos Zivkovic)The Baeldung guide mentions setting up redirection URIs for the authorization code flow, but this is not directly represented in the
application.yml
. If using the authorization code flow, make sure the redirect URIs are correctly configured in the Azure AD application registration and, if necessary, specified in your Spring Security configuration.Make sure the URLs for
issuer-uri
andjwk-set-uri
are correctly typed and match your Azure AD configuration. Typographical errors in URLs can lead to failures in fetching the necessary metadata and keys.If you are using
private_key_jwt
, make sure Azure AD is configured to accept a JWT signed with your private key as a means of client authentication.Depending on the OAuth flow you are using (e.g., authorization code vs. client credentials), make sure the
authorization-grant-type
is correctly specified in theregistration
section. That is not included in the provided configuration but is necessary for some OAuth flows.Since your error message complains about not having
client-id
in request body, I’d suggest you to set theclient-authentication-method
parameter (next to theclient-id
property) in yourapplication.yml
file toclient_secret_post
.By looking at
org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequestEntityConverter.createParameters(OAuth2ClientCredentialsGrantRequest)
method, by setting this parameter, it’ll send the client_id in request bodySame logic applies to other related classes :
org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequestEntityConverter
org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequestEntityConverter
org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequestEntityConverter
Hope it’ll solve your problem
The Microsoft documentation describes the necessary information that should be provided in order to perform an access token request with a certificate.
You need to perform a HTTP request like the following:
In addition to the Entra ID tenant and the app client id, you need to indicate the client assertion type, it is a constant value, and a client assertion.
The client assertion is a JSON web token created and signed with the certificate registered as credentials for the application in the Azure Portal.
The characteristics of this JSON web token are described in detail here.
Using this type of authentication mechanism with Spring Boot is not obvious but fortunately you can find different examples that exemplifies how to that.
Consider for instance this excellent one provided as part of the azure samples repository in Github.
Basically, it defines a set of helper classes, especially one defined in order to provide the
client_assertion
andclient_assertion_type
parameters when performing the request:and another one used to generate the appropriate JWT web token:
This configuration class glues everything together:
Please, pay especial attention to the
accessTokenResponseClient
method.Finally, this is the relevant configuration:
Please, don’t forget to set the appropriate value for the different placeholders defined in the above configuration.