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

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.

Related

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

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.

Spring Boot azureAD filter autoconfiguration

I few days ago I was able to configure the integration with Azure AD and spring boot.
I'm usisng the following dependencies to achieve that:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-active-directory-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
</dependency>
</dependencies>
It works so nice and I was able to get the expected result, but now the problem.
I have to Security configurations. Each one are configured with spring profiles, for example:
spring:
profiles:
active: DDBBSecurized, local
This one enables the sucurity with DDBB and it was configuired before the integration with AzureAD, It works perfect
I also have
spring:
profiles:
active: ADDSecurized, local
that enables the integration of azure AD.
Before configuring Azure AD integration if I use DDBBSecurized it works nice and I also had a option that if I dont configure anyThing. spring.profiles.active: local, for example, it disable the security:
the way to achive that is the following:
#EnableWebSecurity
#Profile( "DDBBSecurized" )
public class DDBBSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationExceptionHandler restAuthenticationExceptionHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS );
http.headers().frameOptions().disable();
//Filtro de autenticacion de peticiones
http.addFilterAfter( new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class );
//Filtros CORS
http.addFilterBefore( new CorsFilter(), ChannelProcessingFilter.class );
//Manejador de excpeciones de login
http.exceptionHandling().authenticationEntryPoint( restAuthenticationExceptionHandler );
//Configuracion Endpoints
http.authorizeRequests().antMatchers( HttpMethod.POST, "/auth/login**" ).permitAll()
.antMatchers( "/v2/api-docs", "/configuration/**","/swagger*/**","/webjars/**" ).permitAll()
.antMatchers( "/actuator/**" ).permitAll()
.anyRequest().authenticated();
}
}
I have my own JWT filter and login endpoint and I also had:
#EnableWebSecurity
#Profile( "!DDBBSecurized & !AzureAdSecurized" )
public class NonSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationExceptionHandler restAuthenticationExceptionHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS );
http.headers().frameOptions().disable();
//Filtros CORS
http.addFilterBefore( new CorsFilter(), ChannelProcessingFilter.class );
//Manejador de excpeciones de login
http.exceptionHandling().authenticationEntryPoint( restAuthenticationExceptionHandler );
//Configuracion Endpoints
http.authorizeRequests().anyRequest().permitAll();
}
}
That works Perfect.
Now If i use ADDSecurized everything works perfect.
#EnableWebSecurity
#Profile("AzureAdSecurized")
public class AzureSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationExceptionHandler restAuthenticationExceptionHandler;
#Autowired
private AADAppRoleStatelessAuthenticationFilter aadAuthenticationFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS );
http.headers().frameOptions().disable();
//Filtro de autenticacion de peticiones
http.addFilterAfter( aadAuthenticationFilter, UsernamePasswordAuthenticationFilter.class );
http.addFilterAfter( new AzureTokenGetFilter(), UsernamePasswordAuthenticationFilter.class );
//Filtros CORS
http.addFilterBefore( new CorsFilter(), ChannelProcessingFilter.class );
//Manejador de excpeciones de login
http.exceptionHandling().authenticationEntryPoint( restAuthenticationExceptionHandler );
//Configuracion Endpoints
http.authorizeRequests().antMatchers( HttpMethod.POST, "/auth/login**" ).permitAll()
.antMatchers( "/v2/api-docs", "/configuration/**", "/swagger*/**", "/webjars/**" ).permitAll()
.antMatchers( "/actuator/**" ).permitAll().anyRequest().authenticated();
}
}
But if I change to DDBBSecurized profile it is still passing the aadAuthenticationFilter filter of azure. even if this configuration is disable. It seems its autoconfigure and WebSecurityAdpater by its Own or something like That.
the properties I also have are:
security:
oauth2:
client:
registration:
azure:
client-id: XXXX-XXXX-XXXX-XXXX-XXXXXXXX
azure:
activedirectory:
tenant-id: XXXX-XXXX-XXXX-XXXX-XXXXXXXX
client-id: XXXX-XXXX-XXXX-XXXX-XXXXXXXX
scope: /User.Read
session-stateless: true
authority-url: https://login.microsoftonline.com/
Now for example I have configured DDBBSecurized And I can see in the log that the filter is being applied:
STARTUPLOG:
2020-03-26 20:10:02,279 INFO class=org.springframework.boot.StartupInfoLogger Starting Application on gggarrido10 with PID 8760 (D:\Proyectos\EvoSago\SOM-Back\admin-user\target\classes started by gggarrido in D:\Proyectos\EvoSago\SOM-Back)
2020-03-26 20:10:11,378 INFO class=org.springframework.boot.SpringApplication The following profiles are active: DDBBSecurized,local
2020-03-26 20:10:31,479 INFO class=org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$2e0e67bf] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-03-26 20:10:33,267 INFO class=org.springframework.boot.web.embedded.tomcat.TomcatWebServer Tomcat initialized with port(s): 8080 (http)
2020-03-26 20:10:34,434 INFO class=org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext Root WebApplicationContext: initialization completed in 22895 ms
2020-03-26 20:10:39,649 INFO class=org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar Registered '/actuator/jolokia' to jolokia-actuator-endpoint
2020-03-26 20:10:42,925 INFO class=org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver Exposing 17 endpoint(s) beneath base path '/actuator'
2020-03-26 20:10:43,850 INFO class=org.springframework.security.web.DefaultSecurityFilterChain Creating filter chain: any request, [es.indra.som.common.utilities.CorsFilter#26f5e45d, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#704c3bdf, org.springframework.security.web.context.SecurityContextPersistenceFilter#1e6d30c0, org.springframework.security.web.header.HeaderWriterFilter#5529522f, org.springframework.security.web.authentication.logout.LogoutFilter#4d2f9e3c, es.indra.som.security.filter.JWTAuthenticationFilter#37986daf, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#69d667a5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#7ab1ad9, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#c82d925, org.springframework.security.web.session.SessionManagementFilter#1b60d324, org.springframework.security.web.access.ExceptionTranslationFilter#43a59289, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#61993d18]
2020-03-26 20:10:45,610 INFO class=org.springframework.scheduling.concurrent.ExecutorConfigurationSupport Initializing ExecutorService 'applicationTaskExecutor'
2020-03-26 20:10:48,503 INFO class=org.springframework.scheduling.concurrent.ExecutorConfigurationSupport Initializing ExecutorService
2020-03-26 20:10:51,398 INFO class=org.springframework.boot.web.embedded.tomcat.TomcatWebServer Tomcat started on port(s): 8080 (http) with context path ''
2020-03-26 20:10:51,407 INFO class=org.springframework.boot.StartupInfoLogger Started Application in 53.341 seconds (JVM running for 56.018)
ERROR LOG BECAUSE THE ADD FILTER IS BEING APPLIED WHEN IT SHOULD'T
2020-03-26 20:11:16,144 ERROR class=com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter Failed to initialize UserPrincipal.
com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:384)
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:330)
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:321)
at com.microsoft.azure.spring.autoconfigure.aad.UserPrincipalManager.buildUserPrincipal(UserPrincipalManager.java:83)
at com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter.doFilterInternal(AADAppRoleStatelessAuthenticationFilter.java:58)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
The point is that before only with DDBBSecurized and NoSecurity ot works perfect. Why for ADDfilter even if I disable it by profile is appliying the filter?
I also tried to
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class , SecurityFilterAutoConfiguration.class,
AADAuthenticationFilterAutoConfiguration.class})
I also tried to delete the full AzureSecurityConfiguration.... but it didnt work, event if I delete the full class it pass the filter
But it did not work and also the app doesnt start because it need AADAuthenticationFilterAutoConfiguration to autoconfigure the filters provided by the library with the properties set in applicacion.yaml avoid the user to manually configure them.
Thanks in advance.

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]

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

Spring Security with Spring Boot

I am trying to create a Spring Boot REST application. When I deploy my application, it authentication is required and it is asking me for user name and password. How can I bypass this or how can I add a user name and password for authentication?
Do I need to remove security entry in pom?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
If you don't want to use authentication at all, you should remove the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
See Spring Boot Reference Guide:
If Spring Security is on the classpath then web applications will be secure by default with ‘basic’ authentication on all HTTP endpoints.
No need of removing security from pom.xml. In your project, you can try something like below. Try to create SecurityConfig which will extend WebSecurityConfigurerAdapter and provide some user name and password and later you can customize it.
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password("user")
.roles("USER")
.and()
.withUser("user2")
.password("secret2")
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated();
http
.httpBasic();
http
.csrf().disable();
}
}
public #interface EnableWebMvcSecurity {
}
Apart from other two answers - default username is 'user' and password will be printed in the console each time you start your server like below -
2019-08-31 23:58:16.417 INFO 12528 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 1ab46edf-332a-42de-ae11-70dc138c65db
Simply use these credentials to login.
Note - If you fine-tune your logging configuration, ensure that the org.springframework.boot.autoconfigure.security category is set to log INFO-level messages. Otherwise, the default password is not printed.
if you wish to configure a username/password of your choice then you can do so in application.properties file.
spring.security.user.name=username
spring.security.user.password=password
Now spring security will not generate a new password each time you boot the application.
Note: When using postman to send requests, go to authorization> select "basic auth"> Enter the username and password so authentication details can be sent along with each request. If using browser, there should be a login page.

Resources