4

I'd like to build admin portal for book management (get, add, delete, update a book). So I began with login/logout feature; the login part works like a charm but I'm facing a problem with logout. When I logout the admin portal keeps the session alive and doesn't kill it and I cannot get any error in log that prove me this issue.

Below a piece of code that response to a post request for logout:

@RequestMapping(value = "/user/logout", method = RequestMethod.POST)
    public ResponseEntity logout(HttpServletRequest request, HttpServletResponse response) {
        SecurityContextHolder.clearContext();

        return new ResponseEntity("Logout Successful !", HttpStatus.OK);
    }

In the client I'm using Angular for sending post request to my local server.Below the logout service:

logout(){
    let url="http://localhost:8090/user/logout";
    const xToken = localStorage.getItem('xAuthToken');
    let headers=new Headers({
      'x-auth-token':xToken,
    });

    return this.http.post(url,{headers:headers});
  }

The xToken variable get the session's token from local Browser storage.

Every time we check if session is kept alive or not in ngOnInit of login component:

ngOnInit() {
    this.login.checkSession().subscribe(
      res=>{
        this.loggedIn=true;
      },
      err=>{
        console.log(err);
        this.loggedIn=false;
      }
    )
  }

The service that is responsible for session's check is detailed below:

checkSession(){
    let url="http://localhost:8090/checkSession";
    const xToken = localStorage.getItem('xAuthToken');
    const basicHeader = 'Basic ' + localStorage.getItem('credentials');
    let headers=new Headers({
      'x-auth-token':xToken,
      'Authorization':basicHeader
    });

    return this.http.get(url,{headers:headers});
  }

For checking the session we request the server:

@RequestMapping("/checkSession")
    public ResponseEntity checkSession() {
        System.out.print("Session Active !");
        return new ResponseEntity("Session Active !", HttpStatus.OK);
    }

basicHeader constant is an authentication scheme that contains an encoded username/password combination stored in browser local storage.

for additional information below how we send credentials to the server:

onSubmit(){
    this.login.sendCredentials(this.credentials.username,this.credentials.password).subscribe(
        res=>{
          console.log(res);
          localStorage.setItem('xAuthToken', res.json().token);
          this.loggedIn=true;
          const encodedCredentials = btoa(this.credentials.username + ':' + this.credentials.password);
          localStorage.setItem("credentials",encodedCredentials);
          location.reload();
        },err=>{
          console.log(err);
        }
    )
  }

Please any help is very appreciated. Thanks in advance for resolving this issue

Mohamed Aoutir
  • 613
  • 3
  • 11
  • 22
  • 2
    why do you not call just logout? i mean '/logout' – Asanka Oct 12 '18 at 18:58
  • when i call just '/logout' it shows me an error of "http://localhost:4200/login?logout 404 not found" I think it's related to spring security formality when using post request – Mohamed Aoutir Oct 12 '18 at 19:17

1 Answers1

2

The logout feature is supported by Spring Security out of the box, it just requires some configuration:

@EnableWebSecurity
@Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {

   @Override
   public void configure(HttpSecurity http) {

       http
           .httpBasic().and() // HTTP Basic authorization or whichever
           .authorizeRequests()
           .antMatchers(...).permitAll()
           .anyRequest().authenticated().and()
           ...
           .logout();
   }

   ...
}

The /logout method then accessible at http://localhost:8080/logout via POST method, assuming your app is launched on localhost through 8080 port.

For more details Spring Security doc

WildDev
  • 2,250
  • 5
  • 35
  • 67
  • 1
    @WilDev I add this configuration but it doesn't work. I think I should add some features in public ResponseEntity logout() of rest controller to invalidate current active session – Mohamed Aoutir Oct 13 '18 at 13:12
  • @MohamedAoutir, the method is provided by Spring Security, no manual implementation required. Direct `POST` request to `http://localhost:8090/logout` endpoint should do the trick – WildDev Oct 13 '18 at 14:01
  • 2
    @Wildev when I logout I clear the browser storage in client by typing localstorage.clear() and it works for me. – Mohamed Aoutir Oct 13 '18 at 17:47
  • I'm seeing the same behavior: My logout controller is NOT being invoked, and the CAS cookie is not being cleared. I can only log in as that same user until I clear that cookie. I can't log in as anyone else. – Marvo May 11 '19 at 16:37