Spring security: set-cookie doesn't work in non-spring environment - spring

I have a spinrg boot app where my frontend code is placed inside the static folder, and everything works great there.
I develop my frontend source outside my spring project and build it to the static folder.
When I run my spring boot app, the frontend works great and the login stores a cookie named JSESSIONID then my API requests work.
The problem is that when I develop my frontend I'm serving my client outside of spring, and the cookie is not stored in my browser upon a successful login.
The question:
Any idea how I can solve it- access and store the cookie although the client is not served with spring?
My spring httpsecurity config:
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/resources/**" , "/assets/**" , "/api/information").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(successHandler())
.failureHandler(failureHandler())
// .failureUrl("/authentication/login-error.html")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())
// .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.and()
.logout()
.deleteCookies("JSESSIONID")
.permitAll();
Set cookie received from spring:
set-cookie:JSESSIONID=1F16D001A85DDD17CE840CF2A3694231;path=/;Secure;HttpOnly

Related

Spring Boot Security: How to run authentication filter before CSRF in Spring Boot?

I am always getting unauthorize on Login.
On Login i need to authenticate user as well as generate CSRF token based on JWT token generated from user credentials.
I have CsrfCookieGeneratorFilter but i need to pass JWT generated after sucessfull authentication. My current code always execute CsrfFilterfirst and after that run authentication thing.
So Authentication First and then CsrfCookieGeneraterFilter.
Could anyone guide how to achieve using following builder (I am quite new to this Spring security thing implementation)
Following is code i am trying:
httpSecurity
.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
.csrfTokenRepository(customCsrfTokenRepository)
.and()
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint);
httpSecurity.addFilterAt(new CsrfCookieGeneratorFilter(customCsrfTokenRepository), CsrfFilter.class);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

Should I disable CORS in spring backend? Unathorized request is blocked

I'm working on project with spring boot and Vue, I need to protect my endpoints. The user will have specific role, admin role or typical user role. When I search for tutorials how to configure JWT and spring security I'm getting articles with disabled cors by cors().disable() only . And that's my question.. May I send request from my front Vue app via axios if cors in spring backend is disabled? Is it right approach to disable it? A lot of my requests from api were blocked by cors so I enabled it but I didn't implement user roles and it made me confused what to do now because I have to do it... Another problem is when I implemented httpSecurity.csrf().disable().authorizeRequests().antMatchers("/authenticate", "/register","/login").permitAll(). and tried to call /authenticate from another device in same network then spring blocked it but it shouldn't be blocked.. On the top of controller I have #CrossOrigin(origins="*", maxAge=3600) and #RestController so I don't know why my request is blocked.
Help me please if You have some ideas.
Best regards!
Set this in top of every controller
#CrossOrigin(origins = "*")
#RestController
And set the code in SecuriyConfig as follows. It worked for me.
httpSecurity.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.ttf",
"/**/*.woff",
"/**/*.woff2",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.jpeg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/authenticate", "/register","/login")
.permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()
.anyRequest()
.authenticated();

Is a stateless app compatible with formlogin?

I'm struggling for some days with this problem : I have an authentication server with spring security. I use JWT tokens, and as I need my users to be able to logout from the font side, I need not to have a JSESSIONID, so I set the sessionCreationPolicy(SessionCreationPolicy.STATELESS)
Also I need a login form on the authentication server side, which I manage with formLogin().
Unfortunately, if I use those 2 configs at the same time, once the user have submited the login form, he's not redirected back to the front app.
If I drop the SessionCreationPolicy.STATELESS and set the formLogin() part, then the redirection is working, but then I got a session, and logout doesn't work.
If I set SessionCreationPolicy.STATELESS and httpBasic(), then the redirection is working, but of course I don't have the login form.
Is there any way to achieve that?
here the config :
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/token/*").permitAll()
.anyRequest().permitAll()
.and()
.httpBasic()
// .formLogin()
// .loginPage("/login")
// .permitAll()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

Spring Boot https redirect

I deployed a Spring Boot web application to AWS and configured SSL certificate for a domain. Every time I click a Login button mapped to:
#RequestMapping("/login")
public String login(){
return "login";
}
I'm redirected to https login page. However, when a user tries to access a page that requires authorization, he is redirected to unsecured http login page.
My Spring Security look like follows:
http
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/","/css/**","/images/**","/js/**").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/index").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("remember-me")
.logoutSuccessUrl("/login?logout")
.permitAll();
Here is live example: test4test.io
Assuming that connection is secure until it hits application, you will have to add following to security config to make all requests secure.
http.requiresChannel().anyRequest().requiresSecure();
If the tls is terminating at the load balancer(which may not be ideal but there are cases) then this may not work. In such circumstances, in aws alb/nlb, a listener can be added on port 80 which can redirect to port 443. This would not require any change in the application as the redirection happens from hte load balancer before the application gets the request.

405 Method Not Allowed for POST

I have a very simple spring boot application, which is secured by the following code:
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
the idea is to secure "admin" portion. It exposes a REST API.
The problem is all the POSTS returns
405 Method Not Allowed
If I remove the security starter from the application, it works. This makes me believe that the security configuration is the problem. But I cannot find out how.
This should be easy.
POSTs and PUT requests would not be allowed if CSRF is enabled,and spring boot enables those by default.
Just add this to your configuration code :
.csrf().disable()
that is :
http.
.csrf().disable().
authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
Refer docs ,if you need to enable CSRF :
http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#csrf-configure
This can also happen if using Spring Security SAML extension and your SAMLUserDetailsService returns a UsernameNotFoundException. Seems pretty counter-intuitive, but that's what it does by default (in my experience).

Resources