Common Error Response Debug Guide
This guide aims to help debug common error response scenarios that may occur in a production Broadleaf Microservices deployment.
500 Response - Invalid Redirect URI
Typically surfaced as an error in the AUTH logs and can be seen as a request error on the browser as you will be unable to resolve an application.
Examples:
500 GET /auth/oauth/authorize - Invalid redirect uri does not match one of the registered values.
Request URL: https://mysite.broadleafcloud.com/auth/oauth/authorize?client_id=admin&code_challenge=BqjWCC...&code_challenge_method=S...&prompt=none&redirect_uri=https%3A%2F%2Fmysite.broadleafcloud.com%2Fsilent-callback.html&response_type=code&scope=USER&state=eyJzY29... Request Method: GET Status Code: 500
Issue:
The AUTH service cannot authorize the requested application based on the fully qualified URL being used to access it. The URI being evaluated is not registered.
Debugging Steps:
- Validate that the Authorized Client for the application being accessed has the appropriate Redirect URL's configured.
- In the Admin, you can configure new Redirect URL's under Security > Authorization Servers > Authorized Clients
- You can also check the following tables and columns in the AUTH database manually
- Table: blc_client, Column: default_redirect_uri
- Table: blc_client_redirect_uris, Column: redirect_uri
- Many Broadleaf Installations are configured with a proxy server or load balancer. On those installations, typical implementations enable Spring's ForwardedHeaderFilter (See Spring Security documentation for more details https://docs.spring.io/spring-security/reference/features/exploits/http.html#http-proxy-server ). To support this type of setup the application will look at the appropriate forwarded header filters to determine the appropriate originating request. Ensure that your proxy setup is setting these headers.
401 Cannot get token, expected 2xx HTTP Status code
Request to https://browse:9447/api/catalog-browse/browse/categories raised an exception
org.springframework.web.reactive.function.client.WebClientResponseException$Unauthorized: 401 Cannot get token, expected 2xx HTTP Status code
Debugging Steps:
- A configured Authorized Client in AUTH (e.g. catalogbrowseclient, cartopsclient, orderopsclient, etc...) See Table: blc_client in the AUTH database.
- Credentials Configured for that Authorized Client which consists of 2 parts
- The calling microservice needs to have a spring application property configured with the appropriate secret injected and ready when the application starts up:
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_[MYCLIENT]_CLIENTSECRET=my_client_secret
- The AUTH service needs to have a BCrypted version of that same secret stored in the database. See Table: blc_client Column: client_secret in the AUTH database.
- The calling microservice needs to have a spring application property configured with the appropriate secret injected and ready when the application starts up:
If these credentials do not line up, then when a service tries to obtain any access token to call another service, it will fail obtaining one from the AUTH service with a "401 Cannot get token". Check the client secrets are as expected. If keys have recently changed, you may need to restart the calling application and AUTH in order for it to pickup the new keys.
WebClientResponseException: 401 Unauthorized from GET/POST
com.broadleafcommerce.[calling-service].exception.ProviderApiException: org.springframework.web.reactive.function.client.WebClientResponseException$Unauthorized: 401 Unauthorized from POST https://[receiving-service]/[endpoint]
In order for a service to communicate with another service, the calling service must request a valid JWT Access Token from Broadleaf's AUTH service first. In this situation, the calling service obtains a JWT Access token, however the receiving service cannot validate it and will throw a "401 Unauthorized".
- Verify these properties have been injected and initialized on all your AUTH services as you would expect:
broadleaf.auth.security.oauth2.encodedPublicKey=MIIBIj... broadleaf.resource.security.oauth2.encodedPublicKey=MIIBIj... broadleaf.auth.security.oauth2.encodedPrivateKey=MIIEvgI...
# note that broadleaf.auth.security.oauth2.encodedPublicKey and broadleaf.resource.security.oauth2.encodedPublicKey should be the same value - Verify this property has been set for ALL OTHER Broadleaf services that make use the AUTH service
broadleaf.resource.security.oauth2.encodedPublicKey=MIIBIj...
# note that this should match the public key set in AUTH - OPTIONAL: In "all other" services (i.e. not AUTH) If the above property is not set or is explicitly set to null/empty, then there is an option to set the well-known JWK endpoint so that the application can fetch the JSON public key directly from the AUTH service on start up
broadleaf.resource.security.oauth2.jwkSetUri=http(s)://<auth_cluster_dns>/auth/.well-known/jwks.json
If the public and private keys of the services do not match, the receiving services will fail to authenticate and will be unable to use the received JWT Access Token. Applications will load the public/private keys during application startup. If keys changes, all the relevant actors may need to be restarted in order for those keys to be picked up and used properly.
You may encounter this error when a Broadleaf microservice (typically a composite/orchestration service like catalogbrowse, cartoperations, and orderoperations) attempts to make a call to another Broadleaf microservice, but fails trying to invoke a particular endpoint on the other microservice.
Example:
com.broadleafcommerce.[calling-service].exception.ProviderApiException: org.springframework.web.reactive.function.client.WebClientResponseException$Forbidden: 403 Forbidden from GET https://[receiving-service]/endpoint
at com.broadleafcommerce.[calling-service].service.provider.external.AbstractExternalProvider.executeRequest(AbstractExternalProvider.java:125 undefined)
Issue:
The calling service has forwarded a valid JWT access token from the AUTH service, however the endpoint on the receiving service has determined that the access token does not have the appropriate SCOPES in order for the request to proceed.
Debugging Steps:
- If you have the ability to mimic the call locally, attempt to retrieve the JWT Access Token and use https://jwt.io/ to inspect the contents of the token. Verify any scopes being requested for that specific call are as you would expect.
- Verify that the correct scopes for this client call are configured in the AUTH database
- Table: blc_client_permissions
- Table: blc_client_scopes
- Table: blc_security_scope
- Table: blc_permission_scope
The application could not be resolved: Request failed with status code 404 - commerce-nextjs-starter (commerceweb)
When first setting up an environment (particularly on a cloud environment that may utilize a cloud native load balancer/proxy ingress) you may run into an error on the "commerceweb" storefront application being unable to resolve applications properly.
Example:
The application could not be resolved: Request failed with status code 404
Issue:
The commerce storefront has a somewhat complex application resolution strategy by default (assuming the standard reference architecture setup). The following diagram represents a typical resolution path for an initial application request to a storefront application:
Ingress/LB
> commercegateway (i.e. /* [fallback to commerceweb])
> commerceweb (i.e. to resolve tenant and application)
> commercegateway
> commerceweb (i.e. /api/commerce/tenants/resolution?... providing basic caching support)
> commercegateway
> Tenant Flex Package (i.e. /api/tenant/* for backend tenant and application resolution)
The "commerce-nextjs-starter" assumes there are several headers present on the request to aid in both tenant and application resolution.
Specifically in the provided accelerator starter, see app/common/utils/tenant-utils.ts
for more details. By default, the application resolution strategy assumes that there is a x-forwarded-host
header defined on the incoming request.
x-forwarded-host
matches exactly the DOMAIN specified for the application and tenant configured in your Tenant microservice.tenant-utils.ts
with configurable logging and additional properties that can help debug the headers and url resolution that is happening by default.-
NEXT_PUBLIC_TENANT_RESOLVER_FORWARD_HEADER
set this property to resolve a different property other thanx-forwarded-host
-
NEXT_PUBLIC_TENANT_RESOLVER_STRIP_PORT_FROM_HOST
set this property to strip any port information from the resolved host (i.e.
:80
,:443
) - default isfalse
-
NEXT_PUBLIC_TENANT_RESOLVER_LOGGING_ENABLED
set this property to enable additional logging for the existing tenant resolution logic
Comments
0 comments
Article is closed for comments.