Hi all I have a newbie grails / spring security question. We set up oauth2 in our grails 3 project using spring-security-oauth2-provider and things seem to work for protecting our REST APIs.
But then we started to add a Web front end in the same project using GSPs and came to a crossroads. Usually oauth2 works by authenticating to an end point and receiving a token, with which it can use in an HTTP header in subsequent requests to keep accessing protected resources. But my Web front end has a login page. So initially we thought to treat the Web front end as one of the clients (we have 1 client for our iOS app and 1 client for our Android app, so why not also have 1 for our web app). But it seems odd to make an HTTP request from our controller code (for logging in) to our oauth2 provider end point because it's in the same project; and most subsequent requests that my Web front end needs to make, we want to directly access underlying services and domain objects so adding an extra hop seems counter-productive.
So what we have opted for is, when I login using my login.gsp, in the controller code, I bypass oauth2 login and just do a straight spring security authentication by using authenticationManager.authenticate() with a UsernamePasswordAuthenticationToken that I construct from the username and password fields passed into my form and then calling SecurityContextHolder.getContext().setAuthentication() on the response. This sort of half solves my problem because I was told from this post that doing so will only set up SecurityContextHolder on the current thread, and since SecurityContextHolder is cleared at the end of the filter chain, subsequent requests won't be authenticated. And so what I did was if this authentication passes (i.e. no exceptions thrown), then I put my user object in the HTTP session and in all subsequent requests, try to retrieve it as a way of "telling" that I am authenticated. But this seems both hacky and dirty; and it leads to my user object not being attached to a DB session (causing lazy initialization exceptions).
I did find other similar suggestions from posts like this which puts the entire SecurityContext in the HTTP session but don't seem to indicate how to use that SecurityContext in subsequent requests.
I guess my ultimate question is, are we going about this the wrong way? Is there a better and cleaner way of accomplishing what I want to do? I suppose we can't be the first people to try to do this.