-
Notifications
You must be signed in to change notification settings - Fork 1.6k
oauth2 logout doesnt really log out, JSESSION are still be retained #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
i've tried a number of things to the sample code which doesn't seem to work for logout. TRIED: Javascript side clearing /uaa JSESSIONID cookie, TRIED: Modified the auth server to session policy = NEVER TRIED: Modified the auth server to sessoin policy = STATELESS Just currious is this the state of security for oauth? Thanks, |
Single logout is subtle, and you have to be careful what you wish for. For instance, if the auth server was Google and the app was your code, I don't think your users would thank you if you logged them out of Google every time they logged out of the app. So the user experience isn't always best served by trying to log out of the auth server at the same time as the app. Indeed, as you have found, it isn't easy to even do that. If you want to do it, your JavaScript client should probably just POST to /uaa/logout, after you configure the CORS protection for that endpoint. However, as soon as you have more than one app authenticated this way, you have the additional headache of trying to decide if you need to try and log out of all of them, or just the one that the user clicked on (it's highly dependent on our own product design). And that's even harder to manage and configure the security rules for. |
Thanks for the reply. Seems like this is the nature of a distributed oauth system that we are trying to setup. Yes we are moving towards a more micro-service/micro-app pattern and seems like we need to lose some of the "monolith" behavior people expect... is this some type of CAPs theory for security? You cant have distributed security for inter-op and have it behave like a monolith at the same time? For now we are asking users to close their browser to end all sessions. Is asking the user to fully close the browser the current industry standard with regards to security? Thanks, |
Closing the browser won't end any sessions, and the cookies are generally persisted locally. Simulating a monolith is an interesting enough idea on it's own that it might deserve a new chapter in the tutorial though. You could play tricks with iframes, and polling to check for a remote single session (chewing up bandwidth). Or, if all your apps are in the same domain, you could use a global cookie. Both ideas probably complicate the security configuration (CORS in particular), but the global cookie seems the cleanest. |
i am trying to configuring CORS on the oauth2-authserver project and modify hello.js to make a cross-site /uaa/logout before posting /logout to oauth2-ui. I was hoping for an easy config in spring boot
...but there seems to be no such configs.. at least that the STS UI is showing. So I am following some sample code for setting up a SimpleCorsFitler.java (see code below) to allow all cross-site requests. I just added this cors filter java next to the AuthServerApplication.java ... Thanks, package demo;
import org.springframework.core.annotation.Order;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
` |
further debugging, the cors filter seems to be running, it is hitting the code, when the cross site if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
// this hits when, the AJAX cross-site request comes
// ||
// VV
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
} but i still see on the hello.js side
below is my hello.js modifications to logout self.logout = function() {
console.log("post logout to uaa...");
$http.post('http://localhost:9999/uaa/logout', {}).finally(function() {
console.log("post log out to ui...");
$http.post('logout', {}).finally(function() {
console.log("redirect to root...");
$rootScope.authenticated = false;
$location.path("/");
});
})
} |
I think my CORS fitler java modification to oauth2-authserver project The JS error only occurs on chrome. I tried clearing all the chrome cookies.. but still fails. Thanks, |
got a bit further... when i added to my SimpleCorsFilter, the content type error went away from chrome. response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization"); now i get this from Chrome.. The POST is making it to oauth2-authserver, and it's trying to redirect... but still the JESSSIONID from /uaa is valid and when i login again... i get the same "Approve/Deny" instead of the /uaa login as i should. btw, Microsoft Edge works fine... logout, click login, get the uaa login page. |
It looks like it is working to me (you can change the logout success handler to send a 200 instead of a 302 if you want to get rid of the JS error there, but it is harmless). Maybe the browser is caching something? |
I finally figured out why chrome wasn't working... and got it to work like Microsoft Edge. Turns out CORS in chrome is way more strict.
So the fix is to modify filters to be more precise with what is allowed and response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
response.setHeader("Access-Control-Allow-Credentials","true"); And on Javascript, you need to ask to send credentials with the AJAX request. $.ajax({
url: "http://localhost:9999/uaa/logout",
method: "POST",
xhrFields: {
withCredentials: true
}, Thanks for all the help. |
Great job Mr nam-pt-do !
It works fine! |
Hi thanks for your posts it helped me a lot. This solution still remembers my last login user so when logout and login for the second time is not prompting me again to provide my credentials it goes straight to approval page. How this can be achieved ? |
@nam-pt-do / @dsyer I am using spring boot Oauth2 implementation for authorization and I have similar requirement for logout , I am wondering if /logout end point there in Authorization server the reason I am asking bcz I have enabled authorization server but when I hit /mappings end point I don't see /logout please can someone help me on that should we write the endpoint by ourself of its already available |
"/logout" is not normally an MVC endpoint (although you could do it that way). It is provided by Spring Security in a filter. |
@dinesh210 Here was my fork of the demo sample code, where logout does a CORS post.
One question additional topic I have is that the CORS. How do you make it so that multiple CORS origin URL is allowed.? For example a user may type http://localhost:9090 on the demo, or http://127.0.0.1:9090 or http://:9090 or http://:9090 of machine. All would work, but only the "http://localhost:9090" would correctly logout since it's currently the only origin URL that's registered in CORS filer. I would like to modify the CORS to allow more than one alias origin URL. |
@dinesh210 , see @Pasha-gharibi's comment above. |
How about this solution ? this will remove oauth server session. You need to logout UI Sever and OAuth server both.
|
@ishara that's a possible solution for some scenarios (it uses Spring Session to share state between multiple apps). There isn't a single solution that would suit everyone. |
@dsyer Hi Dave. I build an auth server by using spring security oauth2 and I used authorization _code grant. Resource server and auth server are spring boot app and i have an angular client. I wrote custom endpoint for revoking token. When I try to log out, token revoking, so I can't access my resource by using that token(it is normal), but I try to sign in again, auth server give me a new token instead of redirecting me to login page. |
@demirmustafa that sounds normal (revoking a token doesn't do anything to the session). |
@dsyer First of all thank you for responding me quickly. |
@nam-pt-do Going through the comments to check if we have a solution for this issue. But was not sure if you found a solution. I took the latest code from master branch. There is no login form presented after user had clicked log out. It goes to approve/deny page after clicking on login button. Just wondering what should be the fix for this issue. |
That's the expected behaviour. |
@dsyer Thanks for your reply and all other replies above. 'Single logout is subtle, and you have to be careful what you wish for. For instance, if the auth server was Google and the app was your code, I don't think your users would thank you if you logged them out of Google every time they logged out of the app.' I agree with your statement but there should be a way to log out user from the app (my code). One way is to have separate authentication for my app where user will login with his credentials for the app and then user will log in again with oauth2 credentials (for first time and again if token is invalid). But is there a way where we can use oauth2 authentication for login and log out for the app? Like making oauth2 as a single sign on ? |
Isn't this a duplicate or closely related to [Support automatically destroying session on OAuth2 authorization server as soon as user redirected to client app] (spring-attic/spring-security-oauth#140) ? The workaround provided there by @dsyer seems to work fine. It's also seems that it would be more correct (if it's really necessary to invalidate session at oauth-server - like in my case and maybe in the case of OP) to invalidate it right after the moment it's not needed any longer and right from auth-server code (not from Zuul, a client app or somewhere else). After successful authentication Zuul initialize it's own session for the user and provide all the resource services behind it with the same access_token stored at the session. It also could automatically update access_token by refresh token with no need in the httpSession (that was created for authentication) at oauth-server. All we need to do when user logs out from the app is to invalidate the session on Zuul, and the pair of corresponding access_token/refresh_token. But it's not an issue of the tutorial. It's just another subject - "how to transform monolith to microservices and separate authentication out of it to another separate service". |
|
Hi,
The sample code for oauth2 doesnt seem to do log out correctly.
code:
tut-spring-security-and-angular-js/oauth2/
auth
ui
resource
when you press login again after log out, there's no prompt for a login screen.
Rather it just goes straight to "approve" dialog.
I looked into the browser cookie and there seems to be 2 JSESSION
One comes from localhost:8080/ from the ui gateway
Second comes from localhost:9999/uaa from the authserver (see fig1 below)
If i manually clear the JSESSION from localhost:9999/uaa then it correctly shows the login form again on re-click of login after logout.
Is there an option to tell authserver to not retain JSESSION?
Or can the springsecurity /logout POST ensure that authserver properly clear JSESSION?
Thanks
Nam
fig1: This cookie should be cleared at logout but is not.

The text was updated successfully, but these errors were encountered: