Reputation: 188
i created a angular 2 and spring security application. After logging in ,when i try to logout it does not logout. After trying 3-4 times it logs out.
Even the "OPTIONS" pre flight call does not appear in network tab.
The login part works perfectly. Let me know if any other code part is required.
Below is my angular service code.
import { Component, OnInit } from '@angular/core';
import { LoginService } from '../login.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
loggedIn: boolean;
constructor(private loginService: LoginService, private router : Router) {
if(localStorage.getItem('PortalAdminHasLoggedIn') == '') {
this.loggedIn = false;
} else {
this.loggedIn = true;
}
}
logout(){
this.loginService.logout().subscribe(
res => {
console.log("logout clicked inside res");
localStorage.setItem('PortalAdminHasLoggedIn', '');
},
err => console.log(err)
);
console.log("logout clicked before reload");
location.reload();
console.log("logout clicked before reload");
this.router.navigate(['/login']);
}
getDisplay() {
if(!this.loggedIn){
return "none";
} else {
return "";
}
}
ngOnInit() {
}
}
Below Spring application code.
package com.userFront.config;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
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.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
try {
chain.doFilter(req, res);
} catch(Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Pre-flight");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type," +
"access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with");
response.setStatus(HttpServletResponse.SC_OK);
}
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
package com.userFront.config;
import java.security.SecureRandom;
import org.hibernate.cfg.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.userFront.service.serviceImpl.UserSecurityService;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserSecurityService userSecurityService;
private static final String SALT="salt";
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}
private static final String[] PUBLIC_MATCHERS= {
"/webjars/**",
"/css/**",
"/js/**",
"/images/**",
"/",
"/about/**",
"/contact/**",
"/error/**/**",
"/console/**",
"/signup"
};
@Override
protected void configure(HttpSecurity http ) throws Exception {
http.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.anyRequest().authenticated();
http.csrf().disable()
.cors().disable()
.formLogin().failureUrl("/index?error").defaultSuccessUrl("/userFront").loginPage("/index").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/index?logout")
.deleteCookies("remember-me").permitAll()
.and()
.rememberMe();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userSecurityService)
.passwordEncoder(passwordEncoder());
}
}
Upvotes: 0
Views: 689
Reputation: 8253
The problem is on here: (it reloads the page and navigats to login, before waiting for logout response.)
logout() {
this.loginService.logout().subscribe(
res => {
console.log("logout clicked inside res");
localStorage.setItem('PortalAdminHasLoggedIn', '');
},
err => console.log(err)
);
console.log("logout clicked before reload");
location.reload();
console.log("logout clicked before reload");
this.router.navigate(['/login']);
}
when you subscribe to result of logout method, you should wait for it to get the result (it's asynchronous.). So change it to:
logout() {
this.loginService.logout().subscribe(
res => {
console.log("logout clicked inside res");
localStorage.setItem('PortalAdminHasLoggedIn', '');
this.router.navigate(['/login']);
location.reload();
},
err => console.log(err)
);
}
Upvotes: 2