Okta-Spring Boot keeps throwing 400 response using company provided okta registration information - spring-boot

Our company provided me with new okta registration information. Specifically, the following :
okta.oauth2.issuer=https://purpleid-test.oktapreview.com/oauth2/aaabbbbccc
okta.oauth2.audience=ABC12345
okta.oauth2.client-id=0oaSomeClientId
In my spring boot application, I have the following :
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
....
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>com.okta.spring</groupId>
<artifactId>okta-spring-boot-starter</artifactId>
<version>2.1.6</version>
</dependency>
</dependencies>
....
</project>
Main class
....
import java.security.Principal;
#SpringBootApplication
public class MessageConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MessageConsumerApplication.class, args);
}
#RestController
#CrossOrigin
static class RootEndpointRestController {
#GetMapping("/test")
String test(Principal principal){
return "test";
}
}
}
application.properties
management.endpoints.web.exposure.include=env,health,info,beans,refresh,bus-refresh
management.endpoint.health.show-details=ALWAYS
management.endpoint.refresh.enabled=true
server.port=8080
okta.oauth2.issuer=https://ourcompanyid-test.oktapreview.com/oauth2/aaabbbbccc
okta.oauth2.audience=ABC12345
okta.oauth2.client-id=0oaSomeClientId
SecurityConfiguration class
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
System.setProperty("https.proxyHost", "internet.proxy.ourcompany.com");
System.setProperty("https.proxyPort", "5555");
http.cors().and()
.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated())
.oauth2ResourceServer().jwt();
}
}
Problem :
Whenever I try to access url like localhost:8080/test or localhost:8080/actuator in the browser (Chrome/Edge), it always returns 400 Bad Request
In the browser URL, this is what shows up
https://ourcompanyid-test.oktapreview.com/oauth2/aaabbbbccc
v1/authorize?
response_type=code&
client_id=0oaSomeClientId&
scope=profile%20email%20openid&
state=I2VByus9KqEt_Zt0ivvG9j_IKtLBldoQrZg-a1SRsYM%3D&
redirect_uri=http://localhost:8080/login/oauth2/code/okta&
code_challenge_method=S256&
nonce=AISpoMaYWFKjp2ZdF_xncSd8LFw7FKTMK9D6G1xbP3o&
code_challenge=hi1EmraZOfOYsdn5rolIaRZO4-pbA8yHtMpIVxjcDP0
However, when I use my personal Okta Developer account registration, it succeeds and redirects me to okta login page when I try to access localhost:8080/test or localhost:8080/actuator in the browser (Chrome/Edge)
My personal Okta Developer account registration looks something like this :
okta.oauth2.issuer=https://dev-123456.okta.com/oauth2/default
okta.oauth2.client-id=0oaMyClientId
okta.oauth2.client-secret=MyClientSecret
I don't have any idea why it would work using my personal Okta registration info and why it would NOT work when I use the Okta registration provided by our company.
Basically, when I use my personal Okta, it redirects to Okta login page just fine. But when I use office provided Okta registration, it returns 400 Bad Request
Is this something to do with my SecurityConfiguration class? Is my configuration class good?
Or, is this something that can be fixed by changing Okta configuration in Okta website?
NOTE: I was informed by the person who created the company okta registration that they created a Single-Page type of Okta registration.
I'd appreciate any comment, explanation or suggestion to fix this.
Thank you.

#RestControllers are OAuth2 resource-servers. Configure it as so. This can be as simple as:
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-addons-webmvc-jwt-resource-server</artifactId>
<version>6.0.4</version
</dependency>
#EnableMethodSecurity
public static class WebSecurityConfig { }
com.c4-soft.springaddons.security.issuers[0].location=https://ourcompanyid-test.oktapreview.com/oauth2/aaabbbbccc
com.c4-soft.springaddons.security.issuers[0].authorities.claims=groups
com.c4-soft.springaddons.security.cors[0].path=/test
Follow link above for samples with more options (servlet VS reactive apps or JWT decoder VS access-token introspection, and last Spring default Authentictaion implementation VS custom ones), and also tips for testing (unit & integration) with mocked OAuth2 identities. Tutorials are providing with instructions for configuring resource-servers with just spring-boot-starter-oauth2-resource-server or spring-addons boot starters building on top of it (and much simplified Java configuration).

Related

SpringBoot OAuth2 Client Google RequestMapping not working in RestController

I am trying to build a SpringBoot OAuth2 Application but stuck with initiating the next POST request of access_token.
This is my code https://github.com/sangeeta-p-shetty/springboot_oauth2_google.git
It runs on http://localhost:8080/security. Currently it successfully redirects to Google and on Sign In redirects to the Redirect URL
Primarily, I am stuck at 3 areas:
#RequestMapping in #RestController is not working.
As RequestMapping is not working, the sample code even though successfully authorizes I am not able to initiate the next POST request of AccessToken. Wanted guidance on how to capture the response from Google and initiate a new request.
I wanted to redirect to OAuth2 only if specific URL is hit in the application. Currently Redirection is happening by launch of context. i.e http://localhost:8080/security
SecurityConfig.java
package com.google.config;
import ....;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// only disable these during testing or for non-browser clients
.cors().disable()
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/oauth2/authorization/google")
.authorizationEndpoint()
.authorizationRequestResolver(
new CustomAuthorizationRequestResolver(
clientRegistrationRepository(), "/oauth2/authorization"));
}
}
application.yml
server:
port: 8080
servlet:
context-path: /security
spring:
security:
oauth2:
client:
registration:
google:
client-id: test.apps.googleusercontent.com
client-secret: test
redirect-uri: http://localhost:8080/security/welcome.html
authorize-uri: https://accounts.google.com/o/oauth2/v2/auth
scope: email
response-type: code
cookie-path-domain: /
cookie-secure: true
provider:
google:
issuer-uri: https://accounts.google.com
SpringBootApplication class
package com.google;
#SpringBootApplication
#ComponentScan("com.google")
public class OidcExampleApp {
public static void main(String[] args) {
SpringApplication.run(OidcExampleApp.class, args);
}
}
AppController.java
Currently in the github code, this class is not included. But below is the intended code which does not seem to get called.
package com.google.controller;
import ...;
#RestController
public class AppController {
#RequestMapping(value="/welcome") // here even If I give value="/welcome.html") it does not work
public String getHi() {
System.out.println("End Point hit*************************************");
return "Hi";
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.codetinkering</groupId>
<artifactId>spring-boot-oauth2-oidc-google</artifactId>
<version>1.0-SNAPSHOT</version>
<name>oauth2-example</name>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<finalName>security</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.google.OidcExampleApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Logs Screenshot

Spring Security custom HTML login page not recognised using thymeleaf

i have followed this link for all configurations to set link up my custom html page for login. However, when i access localhost/login, i am faced with error status 500.
I am unable to render a simple html page when I access localhost:8080/login.
Are there extra configurations needed?
Should the html page be located at templates folder? How does the application know it should render "login.html" ?
Is my controller being recognised?
config
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
}
controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class LoginController {
#GetMapping("/login")
public String login() {
return "login";
}
}
replacing "login" above with below also shows error.
<h1> Login page <h1>
dependencies in pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
<version>1.4.193</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
login.html is located in templates.
error message:
javax.servlet.ServletException: Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
My folder hierachy:
#RestController is a composed annotation that is itself meta-annotated with #Controller and #ResponseBody indicating a controller whose every method inherits the type-level #ResponseBody annotation and therefore writes directly to the response body vs view resolution and rendering with an HTML template.
That's why I advised replacing #Controller by #RestController.
You will not get static resources in your html file. to get this you have to add this.
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
Its behaving as if it cant find your controller. Did you put it in the same package as the main class or deeper in the hierachy?
The component scan which looks for the controller annotation scans from the package your main class is in and beneath it. If you put the controller further out in your folder hierachy it isnt found.
Ok, I have managed to resolved the error but was not conclusive of the cause of it.
The ultimate fix was to keep the mapping url to "/login" in the LoginController and SecurityConfiguration files, and to changed the naming of my html and thymeleaf's references of it in my controller file and html file name as per below.
#Controller
public class LoginController {
#GetMapping("/login")
public String login2() {
return "login2";
}
}
The main reason I would believe has been causing this is because my application and package name were also named "login" which made thymeleaf unable to refer to the right file properly. I have selected the answer above as best answer for others who faced the issue due to different reasons to try out the same experiment to obtain their useful result.

SpringSecurity gives error 401 Bad Credentials

I am new to Spring Security and was creating a simple app to check authentication and authorization. I am using in memory database. Even when I am giving correct login credentials, I am getting error 401 "Bad Credentials" error.
Also I used permitAll() function at some rest endpoints, yet I get a login prompt on those endpoints also. I tried clearing browser history and cache also yet no success. Please help. I am attaching code.
SecurityConfig.java
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
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
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
//Authentication using In Memory Database
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception{
authenticationManagerBuilder.inMemoryAuthentication()
.withUser("user").password("{noop}pass123").authorities("ROLE_USER")
.and()
.withUser("admin").password("{noop}pass123").authorities("ROLE_USER","ROLE_ADMIN");
}
//Authorization
#Override //Overriding configure to use HttpSecurity for web based HTTP requests
public void configure(HttpSecurity httpSecurity)throws Exception{
httpSecurity.
authorizeRequests()
.antMatchers("/protectedbyuserrole*").hasRole("USER")
.antMatchers("/protectedbyadminrole*").hasRole("ADMIN")
.antMatchers("/","/notprotected").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
SpringSecurityApplication.Java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
#SpringBootApplication
#ComponentScan({"com.example.demo","controller"})
#Import({SecurityConfig.class})
public class SpringSecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityApplication.class, args);
}
}
TestSecurityController.Java
package com.example.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class TestSecurityController {
#RequestMapping("/")
public String Hello() {
return "Hello World!! ";
}
#RequestMapping("/notprotected")
public String HelloAgain() {
return "Hello from a non protected user!! ";
}
#RequestMapping("/protectedbyuserrole")
public String HelloUser() {
return "Hello User Role!! ";
}
#RequestMapping("/protectedbyadminrole")
public String HelloAdmin() {
return "Hello Admin Role!! ";
}
}
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.19.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringSecurity-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringSecurity-1</name>
<description>SpringSecurity for Authentication and Authorization</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
QUERIES
Also let me know how to use simple passwords which I can use in postman. Should I use {noop} or just simply writing the password like .password("pass123").
Should I use single * or ** asterisk in .antmatchers()
I tried it using Postman also and Firefox also. Same error everywhere.
POSTMAN SCREENSHOT
Specifying a particular method (GET, POST etc.) in RequestMapping is a good practice you may need to follow.
I have shared a basic example which I have done in the past.
You can try in the browser with username as myusername and password as a mypassword
If you still face the problem let me know with your postman screenshot
#Override
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("myusername")
.password("mypassword")
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http
.csrf().disable()
.authorizeRequests().antMatchers("/login","/home","/failure").permitAll()
.antMatchers(HttpMethod.POST,"/admin/**").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT,"/admin/**").hasRole("ADMIN")
.antMatchers(HttpMethod.GET,"/admin/**").hasRole("ADMIN")
.antMatchers(HttpMethod.GET,"/user/**").hasAnyRole("ADMIN","USER")
.antMatchers(HttpMethod.POST,"/user/**").hasAnyRole("ADMIN","USER")
.anyRequest().authenticated();
}
EDIT
The mapping matches URLs using the following rules:
? matches one character
matches zero or more characters
** matches zero or more directories in a path
{spring:[a-z]+} matches the regexp [a-z]+ as a path variable named "spring"
Refer Path Matcher Here
#RequestMapping(value="/protectedbyuser",method=RequestMethod.GET)
public String Hello() {
return "Hello Protected By User!! ";
}

Spring Boot 2.1.0 with Jersey

Today i started a simple application spring boot application. Because i am starting from the scratch, i am using the latest version of SpringBoot: 2.1.0.RELEASE
I would like to use Jersey to use JAX-RS. I have this working for 1.3.6 Spring Boot version, but I am getting the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'requestContextFilter', defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
I can't understand where the problem could be because my application at this point is minimalist.
Apparently the bean 'requestContextFilter' is being configured twice but i have no idea where it is configured.
Here is my configuration:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>pt.msoftware.userauthservice.App</start-class>
<java.version>1.8</java.version>
<docker.image.prefix>${user.name}</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
SpringBoot application class
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
** Jersey Config**
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
import pt.msoftware.userauthservice.rest.UserEndpoint;
import javax.ws.rs.ApplicationPath;
/**
* Created by marco on 31/10/2018.
*/
#Component
#ApplicationPath("/rest")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(UserEndpoint.class);
}
}
** Endpoint**
import org.springframework.stereotype.Component;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
/**
* Created by marco on 31/10/2018.
*/
#Component
#Path("/user")
public class UserEndpoint {
#GET
public String message() {
return "Hello";
}
}
Can someone spot what I am missing or what might be wrong with my code/config?
Thank you so much
It's a bug in Spring Boot. Thanks for bringing it to our attention. I've opened this issue to track the problem.
If you intend to only use Jersey and JAX-RS, you do not need to use spring-boot-starter-web. It's, essentially, a Spring MVC-based equivalent of spring-boot-starter-jersey. You can, therefore, avoid the problem you're seeing by removing the spring-boot-starter-web dependency from your application.
If you do want to use both Spring MVC and JAX-RS, you can enable bean definition overriding by adding spring.main.allow-bean-definition-overriding=true to your application.properties file in src/main/resources.

spring config server encrypt forbidden

I've configured a spring cloud config server to use oAuth2 for security. Everything is working well, except the encrypt end point. When I try to access /encrypt I get a 403 Forbidden. I am including the Authorization Bearer token in the header. Is there a way to allow the encrypt end point to be called when the server is secured with oAuth, or is it always blocked? Let me know if you would like to see any config files for this server.
Just for reference, here are the things that are working.
calling /encrypt/status produces {"status":"OK"}
The git repository is being pulled because I can access a property file from the server.
oAuth authentication is working with Google because it takes me through the logon process.
Here is the spring security settings.
security:
require-ssl: true
auth2:
client:
clientId: PROVIDED BY GOOGLE
clientSecret: PROVIDED BY GOOGLE
accessTokenUri: https://www.googleapis.com/oauth2/v4/token
userAuthorizationUri: https://accounts.google.com/o/oauth2/v2/auth
scope:
- openid
- email
- profile
resource:
userInfoUri: https://www.googleapis.com/oauth2/v3/userinfo
preferTokenInfo: true
server:
port: 8443
ssl:
key-store-type: PKCS12
key-store: /spring-config-server/host/tomcat-keystore.p12
key-alias: tomcat
key-store-password: ${KEYSTORE_PASSWORD}
Here are my dependencies from the POM file so you can see the version of the libraries I'm using.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.M8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I solve it implementing this WebSecurityConfigurer. It disables CSRF and set basic authentication.In Spring Boot 2.0.0 you cannot disable CSRF using properties it forces you to implement a java security config bean.
package my.package.config.server;
import org.springframework.context.annotation.Configuration;
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
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.httpBasic();
;
}
}
Hope it helps
We must implement WebSecurityConfigurerAdapter in configuration related class. So that the encrypt/decrypt services can be accessible. Make sure that you have configured secret.key in bootstrap.properties or application.properties.
WebSecurityConfigurerAdapter is deprecated
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
Try the following instead of:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.httpBasic();
return http.build();
}
}
To fix this issue, I needed to extend WebSecurityConfigurerAdapter and in the configure method I disabled CSRF token.
http
.csrf().disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/error**")
.permitAll()
.anyRequest().authenticated();

Resources