Azure AD OpenID Connect - redirect_uri query (?client_name=AzureADClient) unsupported by Microsoft?

791 views
Skip to first unread message

David Dascalescu

unread,
Apr 24, 2017, 1:18:17 PM4/24/17
to pac4j-users
Hello all,

Has anyone recently tested Azure AD OpenID (org.pac4j.oidc.client.AzureAdClient) by creating a brand new application in Microsoft Application Console (https://apps.dev.microsoft.com/) and using it (that is, not testing an older application)? It seems that Microsoft is not permitting to have redirect URLs with query strings. Upon entering

The error in the Microsoft Application Console when adding the above Redirect URL is:
"Your URL must be in a valid URL format, begin with https://, and be limited to 255 characters in length."

So the only option is to set just "https://localhost:8443/callback" hoping the query part is ignored when matching. But it is not. Upon going to "https://localhost:8443/azure" I am correctly redirected to Microsoft:


Then permissions are asked for, then I log in successfully using the Azure AD account, but, then, still on the Microsoft side the following error is presented, indicating that an exact match is required:

<<
Sign In
Sorry, but we’re having trouble signing you in.
We received a bad request.

Additional technical information:
Correlation ID: 4395b519-6f27-4428-83a6-185f8c41af42
Timestamp: 2017-04-24 15:47:00Z
AADSTS50011: The reply address 'https://localhost:8443/callback?client_name=AzureADClient' does not match the reply addresses configured for the application: '82a7d68d-41bb-4c2b-91a8-69d07f5daf62'. More details: not specified
>>

Note that I used the latest spring-security-pac4j-demo where I configured tomcat for SSL authentication (as it was easier than configuring jetty plugin) and Microsoft is requiring SSL, then I configured the beans and their references for AzureAdClient in securityContext.xml:

    <bean id="azureSecurityFilter" class="org.pac4j.springframework.security.web.SecurityFilter">
        <property name="config" ref="config" />
        <property name="clients" value="AzureADClient" />
    </bean>
    <security:http create-session="always" pattern="/azure/**" entry-point-ref="noEntryPoint">
        <security:custom-filter position="BASIC_AUTH_FILTER" ref="azureSecurityFilter" />
    </security:http>

    <bean id="azureClient" class="org.pac4j.oidc.client.AzureAdClient">
  <property name="name" value="AzureADClient"/>
        <property name="clientID" value="82a7d68d-41bb-4c2b-91a8-69d07f5daf62"/>
        <property name="secret" value="..."/>
        <property name="discoveryURI" value="https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"/>
        <property name="callbackUrl" value="https://localhost:8443/callback"/>        
    </bean>
    
And I added <ref bean="azureClient" /> to the "clients" bean.

If using the discoveryURI without v2.0 upon successful Microsoft authentication I am redirected to localhost but with no client_name parameter (it is removed from the redirect uri parameter) and the Stack trace is accordingly:

SEVERE: Servlet.service() for servlet [default] in context with path [] threw exception
org.pac4j.core.exception.TechnicalException: name cannot be blank
        at org.pac4j.core.util.CommonHelper.assertTrue(CommonHelper.java:134)
        at org.pac4j.core.util.CommonHelper.assertNotBlank(CommonHelper.java:145
)
        at org.pac4j.core.client.Clients.findClient(Clients.java:131)
        at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:70)
        at org.pac4j.springframework.security.web.CallbackFilter.doFilter(CallbackFilter.java:88)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        ...

I also tested the discoveryURI without v2.0 with an application created in the old style in Azure AD (v2.0 must not be created in Azure AD), which apparently lets me set a reply URL with ?client_name in it and the same as above - no client_name parameter upon return.

Note that the Microsoft rules seems now different related to where you create the the application. These URLs seem that no longer describe the correct application registration for v2.0:
https://msdn.microsoft.com/en-us/library/azure/dn645541.aspx (as recommended in the Pac4j Javadoc for AzureAdClient)

But rather these ones:

I am somehow hoping that I am doing something wrong or at least there is still a solution to use pac4j for AzureAD OpenID Connect other than using a default client because we are developing a multi tenant application and there may be more customers requiring Azure AD authentication and we need one client instance for each. 

Thank you,
David Dascalescu

Jérôme LELEU

unread,
Apr 25, 2017, 7:25:51 AM4/25/17
to David Dascalescu, pac4j-users
Hi,


To sum up, I wrote:
If you finally need to remove the client_name parameter, you need to:
- define the defaultClient on the Clients as the AzureAdClient
- prevent the addition of the client_name parameter with azureAdClient.setIncludeClientNameInCallbackUrl(false);

Which won't work in your multi-tenant use case. You will need some custom callback endpoint, like for example: /callback/{tenant} and a custom logic to pick up the right client.

Thanks.
Best regards,
Jérôme



--
You received this message because you are subscribed to the Google Groups "pac4j-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Dascalescu

unread,
Apr 25, 2017, 9:36:53 AM4/25/17
to pac4j-users, david.da...@gmail.com
Hello Jérôme,

Thank you so much for your reply. Indeed using a custom callback is the route we were tackling; however I prefer using something as much as possible similar to the other clients and to the out of the box settings (we encode the tenant in the client name). Do you think that in the future having the parameter client_name in a path segment:
/callback/client_name=AzureAD/
Instead of query
/callback?client_name=AzureAD

could be of general interest? For example could it be treated automatically in the DefaultCallbackLogic, or maybe via a boolean client property which will assert the position either in query or in path? I have tested and Microsoft is allowing for such an URL and it is also standard (not that the query wasn’t).

I am considering this, because this will keep changes/differences to a minimum with no need to prevent the addition of the client_name parameter with setIncludeClientNameInCallbackUrl(false) and will be a more uniform way to treat all the indirect clients. Now, for example the org.pac4j.core.client.Clients code is generally testing for this parameter as below:
if (indirectClient.isIncludeClientNameInCallbackUrl() && indirectClientCallbackUrl != null && !indirectClientCallbackUrl.contains(this.clientNameParameter + "=")) {

so it is not requiring that the client_name parameter be in the query part in the client’s callbackUrl property.

I am also thinking that if other future general or in-house providers are forbidding the query part this will also help. (During my investigations where I failed to discover the existing thread you mentioned (I am sorry for wasting your time more than necessary), I rather managed to peek on some custom OAuth2 providers dev lists where query was also an issue and they would question the necessity of query rather than correctly following the standard).

Thank you and kind regards,
David Dascalescu
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.

Jérôme LELEU

unread,
Apr 26, 2017, 1:57:29 AM4/26/17
to David Dascalescu, pac4j-users
Hi,

I had never thought about having such customized callback URL, but as the clients are gathered in the Clients component which is also used to retrieve them, I have the feeling that subclassing the Clients component should allow you to do exactly what you want.

The following methods: protected void updateCallbackUrlOfIndirectClient(final IndirectClient indirectClient) and public Client findClient(final WebContext context) could be overridden for your needs.

We could certainly even go further on this by creating some interface and implementations or some delegated component to handle the addition and retrieval of the client name.

Thanks.
Best regards,
Jérôme

 

To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users+unsubscribe@googlegroups.com.

David Dascalescu

unread,
Apr 26, 2017, 12:09:03 PM4/26/17
to Jérôme LELEU, pac4j-users
Hello Jérôme  - Thank you very much for your confirmation. We're fine with this approach.

Kind regards,
David Dascalescu
Reply all
Reply to author
Forward
0 new messages