Warm tip: This article is reproduced from serverfault.com, please click

Problem to logout in java app with oauth2 and Google / Azure auth server

发布于 2020-09-22 16:33:46

I'm having a problem and I need some advice. The situation is the following, I have a very simple java module with spring security and a protected HTML page. The only thing this module does is authenticate against Google / Azure and if the credentials are correct it takes me to the HTML page. Implement OAuth2 and Spring security 5. Authentication works without problems, I get the idTokens, access token, and refresh token (in the case of Azure). The problem arises when trying to logout (button in HTML call to "app/logogut" URL). I see that what refers to the local security context is deleted, there are no cookies and there is nothing left in the browser's storage, however, the session on the external server (Google / Azure) is still active and when I refresh the page I am still logged in. If I open a new tab with Gmail, I enter directly without logging in and if I log out from Gmail, when I refresh the first tab now, it asks for the user and pass again. My query is if I am missing something for the logout to completely close the session through Spring security?

Also, try to do a GET to the URL of each server to log out, that seems to work, but it would not be desirable to go that way -CORS Problem :(-.

My security config

enter image description here

In-text

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/", "/login**").permitAll()
            .anyRequest().authenticated()
            .and()
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/app/logout"))
            .addLogoutHandler(new HeaderWriterLogoutHandler(
                    new ClearSiteDataHeaderWriter(
                            ClearSiteDataHeaderWriter.Directive.CACHE,
                            ClearSiteDataHeaderWriter.Directive.COOKIES,
                            ClearSiteDataHeaderWriter.Directive.STORAGE)))
            .and()
            .oauth2Login()
            .and().csrf().disable()
    ;
}

My Controller

 @Autowired
@PreAuthorize("hasRole('ROLE_USER')")
@GetMapping("/restricted")
public String restricted() throws IOException, URISyntaxException {
    URL resource = getClass().getClassLoader().getResource("static\\Protected.html");
    if (resource == null) {
        throw new IllegalArgumentException("file not found!");
    } else {

        File html = new File(resource.toURI());
        List<String> strings = Files.readLines(html, StandardCharsets.UTF_8);
        StringBuffer sb = new StringBuffer();
        for (String s : strings) {
            sb.append(s);
        }
        return sb.toString();


    }

}

HTML PAge

enter image description here

Any help would be appreciated!

Thanks in advance

Questioner
MarceloM
Viewed
0
MarceloM 2020-12-03 13:10:27

Finally, after all this time, I found a solution to my problem. Following Spring documentation (https://docs.spring.io/spring-security/site/docs/5.2.x/reference/html/oauth2.html#oauth2login-advanced-oidc-logout) I found what some calls Single Sign Out and can be implemented if the issuer-uri is specified in application.properties. This uri returns a json where, among other data, is the end_session_endpoint url.

my application.properties

With this now you can configure OidcClientInitiatedLogoutSuccessHandler like this

SecurityConfig.java

This allows that when logging out from my application, the previous handler is invoked and invalidates the session in the authorization server.

Thank you very much for the help