Closed Pieter-1337 closed 4 months ago
Hi Peter, I am working currently at two customer projects where the auth servers don't comply to the standards. In the course of this work I also refactored a lot how the gateway authenticates to the microservices. In introduced a so called auth strategy which can be individually configured for each route in the gateway. See a first example here: https://github.com/fancyDevelopment/Fancy.ResourceLinker-Sample/blob/bug/entra-id/src/Sample.Gateway/appsettings.json Currently all works fine with the right new configuration with Azure EntraId, Auth0 and now I get the next customer with again another auth server. I plan to check how it is working there and then the lib is in production with 4 different auth servers. If this is working then I plan to release a 1.0.0 version an then I will not implement breaking changed within the major version. As long as a 0 is leading the version number I feel free to always introduce breaking changes ;-)
Hi Daniel, I tried setting my the Authentication section of the routes in routeSettings to AzureOnBehalfOf, TokenPassThrough, and ClientCredentials only. I am a bit unsure to what I should set it?
I authenticate via Azure AD B2C: On the AzureOnBehalfOf setting I still got the same error as in the ticket here. On the ClientCredentialsOnly I get:
An unhandled exception occurred while processing the request.
HttpRequestException: Response status code does not indicate success: 400 (Bad Request).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
Stack Query Cookies Headers Routing
HttpRequestException: Response status code does not indicate success: 400 (Bad Request).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
Fancy.ResourceLinker.Gateway.Routing.Auth.ClientCredentialOnlyAuthStrategy.GetTokenViaClientCredentialsAsync()
Fancy.ResourceLinker.Gateway.Routing.Auth.ClientCredentialOnlyAuthStrategy.GetAccessTokenAsync()
Fancy.ResourceLinker.Gateway.Routing.Auth.ClientCredentialOnlyAuthStrategy.SetAuthenticationAsync(HttpContext context)
Fancy.ResourceLinker.Gateway.Routing.GatewayPipeline+<>c+<<UseGatewayPipeline>b__0_0>d.MoveNext()
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
Fancy.ResourceLinker.Gateway.AntiForgery.GatewayAntiForgery+<>c__DisplayClass3_0+<<UseXsrfHeaderChecks>b__0>d.MoveNext()
Fancy.ResourceLinker.Gateway.Authentication.GatewayAuthentication+<>c+<<UseGatewayAuthentication>b__3_0>d.MoveNext()
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
I add here a version of my config where i removed/replaced the sensitive information, but you should be able to point me in the right direction I think :)
"Authentication": {
"Authority": "https://pbrcplaygroundb2c.b2clogin.com/pbrcplaygroundb2c.onmicrosoft.com/B2C_1_susi/v2.0/",
"ClientId": "CLientId", //ClentId of the audience (API) we are getting a token for
"ClientSecret": "ClientSecret", //ClientSecret of the audience (API) we are getting a token for
"AuthorizationCodeScopes": "openid email profile offline_access https://pbrcplaygroundb2c.onmicrosoft.com/....../access_api",
"QueryUserInfoEndpoint": false,
//Set cookie timeout => Look into how long this should be for us!
"SessionTimeoutInMin": 1,
"UniqueIdentifierClaimType": "name" //"preferred_username"
},
"Routing": {
//These settings hide our entries behind the gateway!
"Routes": {
//Here we can define the different API routes (urls, we wish to access through our BFF)
"API": {
"BaseUrl": "https://localhost:44340",
//PathMatch => If a request is made and there is no controllerAction that fulfilles the request and the path matches here, we just propagate to the actual API!
"PathMatch": "api/{**path}",
"Authentication": {
"Strategy": "ClientCredentialsOnly"
},
"EnforceAuthentication": true
},
//Here we can define the different frontends we wish to access through our BFF)
"Portal": {
//By specifying the baseUrl of our front-end here we propagate all request for our SPA => example go to https://localhost:44305 and we will load our SPA behind the gateway
"BaseUrl": "https://localhost:4200",
"PathMatch": "{**path}", //Always propagate these requests
"Authentication": {
"Strategy": "ClientCredentialsOnly",
"Options": {
"Scope": "openid email profile offline_access https://pbrcplaygroundb2c.onmicrosoft.com/...../access_api"
}
},
"EnforceAuthentication": false //toggle to start authentication flow when navigating to index.html or with an action to the /login endpoint once navigated to the frontend
}
/*
"Portal2": {
....
}
*/
}
}
}```
I also noticed the enforceAuthentication flag was removed from the routes in the routeSetting, I thought this was quite convenient since not all users on a frontend should login immediately?
Hi Peter, as far as I know Azure AD B2C does not support the Azure on Behalf of flow. So I think you should use the "TokenPassThrough" strategy. I just compiled a documentation of the new auth capabilities. You can find it here: https://github.com/fancyDevelopment/Fancy.ResourceLinker/blob/feature/auth-split/doc/features/authentication.md Would you like read through and provide some feedback to me if this is of help to you?
@fancyDevelopment Hi Daniel, I did some further research, and it seems that in the published 0.0.9 the client Secret is missing from the cookieOptions! I made a branch with my fork from the github repo and attached my solution that was failing that version of the gateway and models and all worked fine, however in the 0.0.9 nuget package version the issue keeps arrising concerning the client secret. I think the difference lies in this:
Published version 0.0.9:
The repo fork :
So I guess the V0.0.9 has a critical issue => the missing client secret in the options . Can you confirm this is the issue?
Hi @Pieter-1337, thanks for your issue. I checked this and I can tell you that it was my intention to remove the ClientSecret. The reason is that my idea was that the gateway shall behave like a public client. A client which is generally not trused to keep some secrets, similar like a single page application in the browser. But since I now implemented the token exchage, its neccessary for the gateway to keep secrets. So I am fine to revert this change. What I have not checked yet is, if this change really makes problems with AD B2C. I think AD B2C should support public clients too.
@fancyDevelopment Do you mind elaborating on why the BFF should be a public client? In the end it lives on a server and not in a browser runtime (like a spa would), those have been the differentiators between a public and confidential client for me. I am curious why we would want to register a BFF as a public client.
@Pieter-1337 You are completely right with what you have written. And I have the same thoughts in my mind. At the very beginning, I thought it could be a good idea if the BFF is as thin as possible and therefore started to treat it as a public client. But with token exchange there is no other way now than to treat it as a confidential client. And all your arguments apply! So I reverted this change. If the ClientSecret is not null or whitespace it gets added to the configuration, if not it is still empty. I just merged all my last changes to master. But did not build new nuget packages yet.
Issue when Updating from Version 0.0.7 to 0.0.8 or 0.0.9
When i downgrade the package back to Version 0.0.7 all works as it should.
No changes made except package upgrade. Issue exists on both 0.0.8 and 0.0.9