How to handle NullBean object when @RequestScope bean could be null

Viewed 89

My spring boot application has been secured with keycloak, everything works well except when I'm trying to load current AccessToken from request.

With the following statements the current Token is loaded from RequestContext:

@Bean
@RequestScope(proxyMode = TARGET_CLASS)
public AccessToken accessToken() {
  return Optional.ofNullable(
          (KeycloakSecurityContext)
              RequestContextHolder.currentRequestAttributes()
                  .getAttribute(KeycloakSecurityContext.class.getName(), SCOPE_REQUEST))
      .map(KeycloakSecurityContext::getToken)
      .orElse(null);
}

and then injected where requested.

@Resource(name = "accessToken")
private AccessToken accessToken;

Eveything works as expected when user is logged and token found in request, but when the request is anonymous and AccessToken has not been found the we have this error:

Caused by: java.lang.ClassCastException: class org.springframework.beans.factory.support.NullBean cannot be cast to class org.keycloak.representations.JsonWebToken (org.springframework.beans.factory.support.NullBean and org.keycloak.representations.JsonWebToken are in unnamed module of loader 'app')

I can't find the right way to handle with the NullBean object. Null check is always successfully passed, either whth if ==null statement, and exception is thrown.

public Optional<TenantAdapter> current() {
   // This is always false
   if (accessToken.equals(null)) {
      return Optional.empty();
   } else {
      // and here exception is thrown
       Map<String, Object> claims = accessToken.getOtherClaims();
    
   }   
}

Do you have any suggestion ?

Thanks Stefano

1 Answers

Try with

@Autowired(required=false)
@Qualifier("accessToken")
private AccessToken accessToken;

@Autowired(required=false) <-- will accept if the bean does not exist in application context.

@Qualifier("accessToken") <-- will allow only a bean with name accessToken to be picked so that autowire is not allowed to pick only by type if only 1 bean is available. This is needed because you already pick by name only using the @Resource(name = "accessToken").

Related