Spring Boot https redirect - spring

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.

Related

redirect users if already logged in to home page spring boot security

I am having a spring boot application where users can log in and access the login. After logging in, the users can still access the login page. I want the logged users don't have access to the login page, instead redirect them to the home page. How can I do this?? I am using spring security to authenticate the users.
This is my current configuration:
http
.authorizeRequests()
.antMatchers("/css/**","/js/**","/register/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll()
If you don't want to use filter, in your login controller #GetRequest("/login") check the user details by principal.getName() and return home view if it's not null.

Spring Boot OAuth2 Single Sign On Concept not working

I am trying to develop OAuth2 Client Application with Single Sign On. I have already developed Authorization Server and tested with Client Credentials flow and its working fine. But when I try to use Authorization Code Grant with Single Sign On I could not get it right. Client application takes me to Login Screen when I access authenticated URL, but once authenticated I am redirected to call back url that's fine. But afterwards I could not access any URL as it all authenticated URL are automatically redirected to CALL BACK url. I have permitted call back url in my Security class
My requirement is once authenticated it will allow other urls normally before authentication it should not allow any url.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeRequests()
.antMatchers("/","/index.html", "/home.html", "/login**","/webjars/**", "/error**","/favicon.ico**","/oauth/token","/oauth/authorize**","/demo/1")
.permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.httpBasic();
Here the call back url is demo/1 and Spring Security is not permitting any other url here.
My requirement is once authenticated it should allow other urls normally before authentication it should not allow any url.
http.authorizeRequests().antMatchers("/","/resources/**", "/**").permitAll().anyRequest().authenticated().and().formLogin()
.loginPage("/").permitAll().usernameParameter("username").passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check").failureUrl("/")
.successHandler(myAuthenticationSuccessHandler()).and().logout().logoutSuccessUrl("/")
.logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("JSESSIONID").and().csrf().disable().headers().frameOptions().sameOrigin();

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);

How to create a spring boot app with ssl.enable=true and a non-secure "/health" end point

Is it possible to configure spring boot application ( Jetty ) to have at least one non-secure (non https) endpoint for a load balancer to perform health checks but have all other requests be forced to be secure?
When setting the property:
server.ssl.enabled=true
requests for all ports (both regular port and management/actuator port) are forced to be https.
Secure requests URLS must have the server name in the URL match the certificate configured. A load balancer or container manager like kubernetes would have to access each node in a pool of servers with some kind of host name to server mapping.
Initially I thought that the setting management.ssl.enable=false would do the trick but it doesn't appear to be the case. What I wound up doing that worked for me was to add an ssl exclusion rule for just the /health endpoint.
Here is an abridged version of my SecurityConfiguration which is a #Configuration annotated class that extends/implements WebSecurityConfigurerAdapter/WebSecurityConfigurer.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/secure-path").hasAuthority("SOME_ROLE")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.permitAll()
.and()
.exceptionHandling();
if (securityProperties.isRequireSsl()) {
//allow health checks to be over http
http.requiresChannel().antMatchers("/health").requiresInsecure();
http.requiresChannel().anyRequest().requiresSecure();
}
}
making use of the requiresInsecure() for the /health endpoint was the key. Note, the order is important, generally in Spring Security more specific rules should come first.
The Spring Boot 2 property for disabling the management server TLS is:
management.server.ssl.enabled=false

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

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

Resources