Getting 403 Forbidden error in Spring Boot security despite CSRF being disabled - spring-boot

For some reason I'm getting a 403 Forbidden error from Spring Boot when I try to do anything with it. I currently have the following in my configure method of my SecurityConfiguration class:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/*", "/console").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and().addFilterBefore(new LoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
I'm new to this part of Spring boot so not sure if this is what's causing it.

Turns out... I'm an idiot. This isn't caused by CSRF at all... It was caused by the fact I'm British and I spell what should be Authorization as Authorisation in my AuthenticationFilter which was choking up everything else.

Related

Spring Boot OAuth2 login endpoint not working. Getting 404 when hitting default path

I want to implement OAuth2 in my Spring Boot App.
I added
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
Basic config for GitHub (for example):
spring:
security:
oauth2:
client:
registration:
github:
client-id: xxx
client-secret: xxx
And basic WebSecurity config allowing all endpoints:
#Configuration
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.antMatcher("/**").authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.oauth2Login();
}
}
When client-id/secret is not provided, an exception occurs so the config is picked up properly.
But I can't access the oauth login page which should be http://localhost:8080/oauth2/authorization/github, I have an 404 instead.

Spring Boot with OAuth2 behind reverse proxy

I'm new with Spring Security and trying to develop Spring Boot app with Google login using OAuth2 which runs under hostname:8080. This app is behind Apache reverse proxy server https://url.com.
Spring Boot version 2.1.0
Spring Security version 5.1.1
build.gradle:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.security:spring-security-oauth2-client")
implementation("org.springframework.security:spring-security-oauth2-jose")
}
application.yml:
oauth2:
client:
registration:
google:
clientId: <clientId>
clientSecret: <clientSecret>
scope: profile, email, openid
server:
use-forward-headers: true
servlet:
session:
cookie:
http-only: false
Spring Security config:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login();
}
}
I request https://url.com
Get redirected to https://accounts.google.com/signin/oauth/
When authenticated get redirected back to
https://url.com/login/oauth2/code/google?state={state}&code={code}&scope=openid+email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.me&authuser=0&session_state={session_state}&prompt=none which timed out with error:
[invalid_token_response] An error occurred while attempting to
retrieve the OAuth 2.0 Access Token Response: I/O error on POST
request for "https://www.googleapis.com/oauth2/v4/token": Connection
timed out (Connection timed out); nested exception is
java.net.ConnectException: Connection timed out (Connection timed out)
Is this error caused by the proxy server settings or boot app? Thanks for help.
Solved. I had to set the JVM parameters:
https.proxyHost=[host]
https.proxyPort=[port]
http.proxyHost=[host]
http.proxyPort=[port]

Spring Boot Security WebFlux functional, cannot created configuration for two authentication methods

I would like to have two ways of authentication in Spring Boot application. App is written with WebFlux and with functional approach. For some of my endpoints I'd like to have authentication with basicHttp and for some endpoints I would like to have JWT authentication using custom HTTP header. However I cannot merge two WebFilterChains or make it work as one. Only one of the methods works at the time, cannot make them both work. Code for JWT is not finished, but I would like to see 401 when I send request with httpBasic auth method. Paths in examples are fake.
My atttemps:
1)
First bean:
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/api/1/**"))
.csrf().disable()
.formLogin().disable()
.logout().disable()
.httpBasic().and()
.authenticationManager(authenticationManager(userService))
.build();
Second bean:
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/2/**"))
.httpBasic().disable()
.csrf().disable()
.formLogin().disable()
.logout().disable()
.authenticationManager(tokenAuthManager)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();
2)
http
.securityMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/api/1/**"))
.csrf().disable()
.formLogin().disable()
.logout().disable()
.httpBasic().and()
.authenticationManager(authenticationManager(userService))
.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/2/**"))
.httpBasic().disable()
.csrf().disable()
.formLogin().disable()
.logout().disable()
.authenticationManager(tokenAuthManager)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();

Migration to Spring Boot 2 from 1.5.7 - Request method POST not supported - csrf already disabled

We've migrated our software from spring boot 1.5.7 to spring boot 2.
We're using JSF by including joinfaces-parent in our pom.xml.
At the startup, all works perfectly, but login call does not work:
Request method 'POST' not supported
It is probably a Spring Security issue? CSRF is already disabled.
Here's our SecurityConfig file:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) {
try {
http.csrf().disable().authorizeRequests()
.antMatchers("/javax.faces.resource/**", Page.LOGIN.getUrlForSecurityContext())
.permitAll()
.and()
........
// *** login configuration
.formLogin()
.loginPage(Page.LOGIN.getUrlForSecurityContext()).permitAll()
.failureUrl(Page.LOGIN.getUrlForSecurityContext() + "?error=true")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.and()
...........
// #formatter:on
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
.......
}
The login request does not arrives to our backend.
I found out that this error is generated from the dispatcher.forward function, called from xhtml. Here the function:
public void login() throws ServletException, IOException {
final ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
final RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/login");
dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
}
Here more logs when the error message happens:
[io.undertow.servlet] (default task-3) Initializing Spring FrameworkServlet 'dispatcherServlet'
16:02:20,926 INFO [org.springframework.web.servlet.DispatcherServlet] (default task-3) FrameworkServlet 'dispatcherServlet': initialization started
16:02:20,938 INFO [org.springframework.web.servlet.DispatcherServlet] (default task-3) FrameworkServlet 'dispatcherServlet': initialization completed in 12 ms
16:02:20,949 WARN [org.springframework.web.servlet.PageNotFound] (default task-3) Request method 'POST' not supported
16:02:20,973 ERROR [org.springframework.boot.web.servlet.support.ErrorPageFilter] (default task-3) Cannot forward to error page for request [/login] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
Thanks in advice!
Spring Security configuration looks ok for me. There is something wrong with your login controller. I suppose your login method is called in response to POST request from the client. Then it tries to forward this POST to render login page and finally throws an exception. Obviously it should be GET request instead of POST.

SpringBoot app - server context Path

I've generated a Spring Boot web application using Spring Initializer, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.
Technologies used:
Spring Boot 2.0.0.M6 , Java 8, maven
Here my security config
#Override
protected void configure(HttpSecurity http) throws Exception {
final List<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains("dev")) {
http.csrf().disable();
http.headers().frameOptions().disable();
}
http
.authorizeRequests()
.antMatchers(publicMatchers()).permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").defaultSuccessUrl("/iberia/list")
.failureUrl("/login?error").permitAll()
.and()
.logout().permitAll();
}
in my application.properties
server.contextPath=/iberiaWebUtils
server.port=1234
But when I run the app at http://localhost:1234/iberiaWebUtils, instead of going to http://localhost:1234/iberiaWebUtils/login, the app. redirects to http://localhost:1234/login
I also tried with
server.context-path=/iberiaWebUtils
with the same result
Starting from Spring Boot 2.0.0 M1 servlet-specific server properties were moved to server.servlet:
Spring Boot 2.0.0 M1 Release Notes
Therefore, you should use the server.servlet.context-path property.
Try adding .loginProcessingUrl("/iberiaWebUtils/login") after loginPage("/login")
http
.authorizeRequests()
.antMatchers(publicMatchers()).permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.loginProcessingUrl("/iberiaWebUtils/login")
.defaultSuccessUrl("/iberia/list")
.failureUrl("/login?error").permitAll()
.and()
.logout().permitAll();

Resources