0
votes

Already spend a day looking for a working solution. I use Spring for the backend and Angular for the front. I use JWT to manage authentication. and I want to store the JWT token in the response cookie after the user login. and then send it back automatically with each request. when the user login successfully in the spring side I add a JWT cookie in the response

    @PostMapping("/getLogin")
    public ResponseEntity<LoginModel> getLogin(@RequestBody LoginFour loginFour, HttpServletRequest request,
                                               HttpServletResponse response) {
        final LoginModel loginModel = userInformationService.getLoged(loginFour,
                loginFour.getIpAdress(), loginFour.getTimeZone());

        Cookie jwtCookie = new Cookie("JWT_TOKEN", loginModel.getJwt());
        jwtCookie.setMaxAge(15 * 60 * 1000);
        jwtCookie.setHttpOnly(false);
        jwtCookie.setSecure(false);
        response.addCookie(jwtCookie);

        return new ResponseEntity<>(loginModel, HttpStatus.OK);
    }

and in the browser when I inspect the network tab I can see the cookie in the response header

enter image description here

then when I send another request the cookie is not sent back in the request header

enter image description here

other cookies stored using angular are ended back with the request but not the jet one provided from the response header of the first request

here is my angular HTTP interceptor

@Injectable()
export class HttpInterceptorService implements HttpInterceptor {

    constructor(private router: Router) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(req.url);
        const reqClone = this.addHeader(req);

        return next.handle(reqClone).pipe(
            catchError((error: HttpErrorResponse) => {
                if (error.status >= 200 && error.status < 300) {
                    return this.handleTextResponse(error);
                } else if (error.status == 403) {
                    localStorage.clear();
                    this.router.navigate(['/auth/login']);
                }
                return this.handleError(error);
            })
        );
    }

    private addHeader(req: HttpRequest<any>) {
        return req.clone({
            setHeaders: {
                'Content-Type': 'application/json'
            },
            withCredentials: true
        });
    }

and here is my spring security config

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    public static final String[] AUTHORIZED_PATHS = new String[]{
            "/login/getLogin",
            "/angularBeanLogin/resetPasswrod",
            "/angularBeanSignup/setUser",
            "/angularBeanTest/getUserSettingAccess",
            "/angularBeanTest/getUserRole",
            "/login/getAllPermitForChart"
    };

    private final UserDetailsServiceImpl userDetailService;
    private final JWTRequestFilter jwtRequestFilter;

    public SecurityConfigurer(UserDetailsServiceImpl userDetailService, JWTRequestFilter jwtRequestFilter) {
        this.userDetailService = userDetailService;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService)
                .passwordEncoder(new PasswordEncoderImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().disable()
                .csrf().disable()
                .authorizeRequests().antMatchers(AUTHORIZED_PATHS).permitAll()
                .anyRequest().authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

didn't understand the reason why the set-cookie is not sent to the server with the other cookies

using angular 5.0.5 and spring boot 2.0.2.RELEASE

1

1 Answers

0
votes

I have used the below code to do add the cookies in each request...

import { Observable } from 'rxjs/Observable';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      withCredentials: true
  });
  return next.handle(request);
  }
}

And add to providers array of app.module.ts as below.

import { AuthInterceptor } from './services/auth.interceptor';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
imports: [
    BrowserModule,HttpClientModule,FormsModule
  ],

providers: [
    {
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
    }
]