These are chat archives for spring-cloud/spring-cloud

13th
Jan 2015
@dsyer I am not crazy it works intermittently. There is only one /user endpoint at that is on the authserver. It simply returns the principal. However sometimes the principal is an instance of usernamePassword authenticationToken and it is an instance of AcmeUserDetails (this is good)
Other times it is an instance of Oauth2Authentication and the userAuthentication has the token however this token is NOT an instance of AcmeUserDetails and does not contain the extra fields (Bad)
It seems on the Auth server side of things that whenever the Oauth2Authentication object is created the usercredentials that are passed to the constructor are correct.
So at this point I think one of the other services are overriting it with the other variation (since its a shared security context in redis)
Dave Syer
@dsyer
Jan 13 2015 16:33
Yes. You need to switch off the session persistence in the services.
Or stop sharing the session
There's no need to share the session if you have an API gateway
I'd understand why you wanted it in the auth server to scale it up.
William Gorder
@wgorder
Jan 13 2015 16:34
Ok is that security.session OFF?
Dave Syer
@dsyer
Jan 13 2015 16:34
This tends to suggest that one of your services is not being called through the proxy as well
William Gorder
@wgorder
Jan 13 2015 16:34
or NONE rather
Dave Syer
@dsyer
Jan 13 2015 16:34
STATELESS
William Gorder
@wgorder
Jan 13 2015 16:34
ok
Well the only one not called through the proxy is the auth server
Dave Syer
@dsyer
Jan 13 2015 16:34
But don't have Spring Session even on the classpath in those services
Then there's no risk
William Gorder
@wgorder
Jan 13 2015 16:35
well the thing is I want to use it for other stuff (like cart data)
so shared session is useful
I just don't want it overriding the security context entry
overwriting rather
Dave Syer
@dsyer
Jan 13 2015 16:36
Ah I see
Possibly I have the same behaviour in my app then
let me check
William Gorder
@wgorder
Jan 13 2015 16:36
ok
Dave Syer
@dsyer
Jan 13 2015 16:37
I have to run and do an errand
Back in 20min
William Gorder
@wgorder
Jan 13 2015 16:42
ok
Dave Syer
@dsyer
Jan 13 2015 17:28
It's the same in my app.
Dave Syer
@dsyer
Jan 13 2015 17:36
It's an interesting problem
I guess the ResourceServerTokenServices should try to load the user by username from a UserDetailsService if there is one. That might be a useful feature generally.
Then you would still need to extract the user in your /user endpoint
e.g.
    @RequestMapping("/user")
    @ResponseBody
    public Principal user(Principal user) {
        if (user instanceof OAuth2Authentication) {
            return ((OAuth2Authentication) user).getUserAuthentication();
        }
        return user;
    }
William Gorder
@wgorder
Jan 13 2015 18:05
yup I had something similar originally if user was an instance I got the userauthentication else I returned the principal. The problem became whenever it was an instance of oauth2authentication it no longer had an instance of UserDetails so I did not have access to firstname, lastname etc
Dave Syer
@dsyer
Jan 13 2015 18:06
The principal name should always be the username that you originally authentcated with
William Gorder
@wgorder
Jan 13 2015 18:06
since the user endpoint is in the auth server I could make a call to the user repository to get the profile info
Dave Syer
@dsyer
Jan 13 2015 18:06
That's what I'm playing with
William Gorder
@wgorder
Jan 13 2015 18:07
yes the principal name was the email (which was what I authenticated with you can contrast the 2 screenshots above)
what I am really looking for is the users 'profile' information
I think we are on the same page :) I was thinking I was nuts there for awhile. Sometimes it appeared to work and other times it didnt
Dave Syer
@dsyer
Jan 13 2015 18:16
This is what I am going with:
    @RequestMapping("/user")
    @ResponseBody
    public UserDetails user(Principal user) {
        return new User(user.getName(), "N/A", ((Authentication) user).getAuthorities());
    }
But you can get more information if you need it from your UserDetailsService (I don't have one because it's just the default Boot authentication)
I guess I might need a Part VI
William Gorder
@wgorder
Jan 13 2015 18:22
Yes its an extra repository call when the application is loaded to get it but it will work
its a quick one anyway
on mine if its an instance of oauth2authentication ill just make a call to the user repository and return the user. Else i will just return the principal
William Gorder
@wgorder
Jan 13 2015 18:27
Yup that will work. I just wanted to make sure I was not missing a different way. I guess I can still remove Spring Session from the services that do not need it. All the CSRF happens on the api gateway (I think)
I had it in my head that if a post request was forwarded by the gateway to another service that services csrf protection would complain (since its activated by default by the presence of spring security)
but I have not tested that
William Gorder
@wgorder
Jan 13 2015 18:59
Ok so almost there... Here is the next one. If I logout it hits the logout endpoint in the api gateway and everything 'looks good'
2015-01-13 13:57:17.368 DEBUG 13347 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : /logout at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@79af7d59: Authentication: org.springframework.security.oauth2.provider.OAuth2Authentication@79af7d59: Principal: minnie@gmail.com; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, sessionId=<SESSION>, tokenValue=<TOKEN>; Granted Authorities: ROLE_USER'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : /logout at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@7b1372d9
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : /logout at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : /logout at position 5 of 13 in additional filter chain; firing Filter: ''
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy : /logout at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/logout'; against '/logout'
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.s.w.a.logout.LogoutFilter : Logging out user 'org.springframework.security.oauth2.provider.OAuth2Authentication@79af7d59: Principal: minnie@gmail.com; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, sessionId=<SESSION>, tokenValue=<TOKEN>; Granted Authorities: ROLE_USER' and transferring to logout destination
2015-01-13 13:57:17.375 DEBUG 13347 --- [nio-8080-exec-8] o.s.s.w.a.l.SecurityContextLogoutHandler : Invalidating session: e943f1bc-6985-4023-8d43-2093c5176327
2015-01-13 13:57:17.392 DEBUG 13347 --- [nio-8080-exec-8] .s.s.w.a.l.SimpleUrlLogoutSuccessHandler : Using default Url: /
2015-01-13 13:57:17.392 DEBUG 13347 --- [nio-8080-exec-8] o.s.s.web.DefaultRedirectStrategy : Redirecting to '/'
2015-01-13 13:57:17.399 DEBUG 13347 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.

However I can log in by pressing login again (no need to enter credentials does not even route me to auth server)
Dave Syer
@dsyer
Jan 13 2015 19:55
It probably does if you trace the requests in your browser
See the blurb about "single sign out" in the README (part V of blog)
William Gorder
@wgorder
Jan 13 2015 20:08
hmm. Ok indeed if I try to hit a protected URL I am redirected to the login page for credentials, however if I just click login (without actually attempting to access a protected resource) I am logged in with no complaints.
I take it this is because the oauth token is left on the session?
only the user part is removed?
Click back on "login" though and you actually don't need to go back through the authentication and approval cycle in the authorization server (because you haven't logged out of that).
actually I figured I had since its all tied to a session (stored in redis) that is cleared on logout
William Gorder
@wgorder
Jan 13 2015 20:17
So if I understand you correctly.. If I were to expose a /logout endpoint on the authserver I would be logged out of everything.
William Gorder
@wgorder
Jan 13 2015 21:04
Its kind of cool actually. I suppose the auth server could theoretically maintain a list of all the sytsems you are logged into and allow you to call their respective logout links
I am curious to how its stored it must be keyed by application context in spring-session or something if it were just by session id then loggin out of the api-gateway would log me out of everything.
of course that would be an edge case (you wouldnt expect github for example to log you out of other applications). So I suppose instead you would expire the token.
William Gorder
@wgorder
Jan 13 2015 21:26
Ok. I guess what you would do is leave it the way it is and treat the auth server kind of like a github or google.
which mean just like a user can choose to logout of github I need to give a user a way to logout of the auth server. that would disable a users ability to automatically login again once logged out