I'm implementing Oauth2 with PKCE in a monolithic application written in Spring 5.2 (not Boot) with Struts 2.5. The application currently keeps users and hashed passwords in its own database, but I'm changing it to use the corporate OAuth2 Okta authorization server, which requires PKCE. From my research, most PKCE implementations have the client side of the OAuth 2.0 protocol flow happen inside a browser that's dealing only with one user at a time.
By contrast, in my case the OAuth2 "client" is really a web server. I have a Struts action on the server that assembles the URI to the authorization server's endpoint, including the transformed code_verifier (code_challenge), and redirects the user's browser to that endpoint. A second Structs action handles the PKCE callback from that authorization server and calls the token endpoint on the authorization server behind the browser's back to obtain an access token for the user's session.
Between the start and the end of the PKCE interaction this "client" web server has to keep track of code verifiers for potentially many users all trying to login at the same time. I can think of two possibilities:
Maintain a map keyed by the random state parameter that is posted to the authorization server in the initial challenge and returned to the callback action. There would have to be a mechanism to purge stale entries from this map that remain from incomplete login interactions.
Generate a random AES key at web server startup which is used solely for encrypting the code verifier, sending the encrypted code verifier as the state parameter, and then decrypting the state in the callback action to recover the code verifier. This wouldn't require maintaining a map in the web server, just this random key. Is there anything insecure with this approach?
I've implemented the second possibility above, and it works, but hasn't been rolled out to production yet for hackers to play with.
If the approach in this answer (also this one) is secure (store the code verifier in an encrypted cookie), then I think my solution would also be secure, but is it necessary to opt for the complexity of a cookie instead of simply the state parameter?