Search code examples
springspring-bootspring-securityoauth-2.0spring-jdbc

Error persisting OAuth2AutorizedClient in Spring Security 5 with JdbcOauth2AuthorizedClientService


I'm trying to use JdbcOauth2AuthorizedClientService to persist the authorized client info such as access_token and refresh_token in a Stateless microservice. I'm getting below error, I never get to resolve the required resource and authorized client info never gets saved in Postgres.

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 500 Internal Server Error: "{"timestamp":1672302575797,"status":500,"error":"Internal Server Error","exception":"org.glassfish.jersey.server.internal.process.MappableException","message":"java.lang.IllegalArgumentException: Unsupported contentType: application/json","path":"/oauth2-v1/oauth2/token"}" enter image description here

Interestingly, when I use the InMemoryOAuth2AuthorizedClientService implementation OAuth2 flow works fine. Error message doesn't look has anything to do with JDBC/DB connection.

I decided to use this implementation per this answer

I'm using the Postgres schema version for table oauth2_authorized_client:

CREATE TABLE oauth2_authorized_client (
  client_registration_id varchar(100) NOT NULL,
  principal_name varchar(200) NOT NULL,
  access_token_type varchar(100) NOT NULL,
  access_token_value bytea NOT NULL,
  access_token_issued_at timestamp NOT NULL,
  access_token_expires_at timestamp NOT NULL,
  access_token_scopes varchar(1000) DEFAULT NULL,
  refresh_token_value bytea DEFAULT NULL,
  refresh_token_issued_at timestamp DEFAULT NULL,
  created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  PRIMARY KEY (client_registration_id, principal_name)
);

I have tried the following:

  1. Read LobHandler interface documentation where it states that different database drivers will behave differently with regards to BLOB data type handling, so in my case, for Postgres, they recommend:
  • Creating a DefaultLobHandler with wrapAsLob = true

Solution

  • I was able to resolve the issue with the following:

    • A small detail that I didn't mention is that I'm using LiquidBase for schema migrations in my project, so Liquibase Spring Boot auto configuration automatically creates schema for me from the schema definitions YAML/XML.
    • I removed my previously created table oauth2_authorized_client
    • I changed my LiquiBase schema definition to remove access_token_value -> NOT NULL constraint and used DEFAULT NULL (same as refresh_token_value).
    • I ran again the application and this time it worked

    Apparently, JdbcOauth2AuthorizedClientService tries to insert an entry with access_token_value null at some point in the flow...