Error when using Spring Security 5 and Auth0 - spring-boot

I am configuring my Spring Boot application using auth0. For that I am using the following tutorial: https://auth0.com/docs/quickstart/backend/java-spring-security5
But I am getting the following error:"
class com.nimbusds.jose.Algorithm cannot be cast to class com.nimbusds.jose.JWSAlgorithm (com.nimbusds.jose.Algorithm and com.nimbusds.jose.JWSAlgorithm are in unnamed module of loader 'app')
I am using Spring Boot 2.5.0-M2, and Kotlin (just in case it matters)

It is a bug in 5.5.0 pre releases of spring security which is used by spring boot 2.5.0.
There is a PR to fix this that hopefully will be released soon.
Until then you can create the JwTDecoder as a workaround:
#Bean
JwtDecoder jwtDecoder() {
String issuerUri = ...;
String jwkSetUri = ...;
OAuth2TokenValidator<Jwt> validator = JwtValidators.createDefaultWithIssuer(issuerUri);
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwtSetUri(jwkSetUri).build();
jwtDecoder.setJwtValidator(validator);
return jwtDecoder;
}

Related

Application failed to start after spring boot version upgrade from 2.1.18.RELEASE to 2.2.0.RELEASE

When we upgrade the spring-boot-starter-parent version from 2.1.8.RELEASE to 2.2.0.RELEASE, the application is not loading few beans. Due to this, application is failing. #PostConstuct is not able to add BCFIPS Provider in security provider.
#Configuration
#Slf4j
#ComponentScan(basePackages = "com.xxx.yyy.ekms.sdk")
#ConditionalOnProperty(name = "ekms.enabled", havingValue = "true")
public class EKMSClientSdkConfiguration extends ClientConfiguration
{
#PostConstruct
public void addSecurityProvider()
{
Security.addProvider(new BouncyCastleFipsProvider());
}
#Bean
public ApiClientBuilder apiClientBuilder()
{
return new DefaultApiClientBuilder();
}
}
Also, apiClientBuilder bean is not getting created.
The EKMSClientSdkConfiguration is extending ClientConfiguration, which is coming as part of another application jar. This class is not having any annotation.
public abstract class ClientConfiguration {
public ClientConfiguration()
{
}
public abstract void addSecurityProvider();
#Bean
public EKMSClient restClient() {
return new EKMSRestClientImpl(this.apiClient());
}
#Bean
public ApiClient apiClient() {
return Configuration.getDefaultApiClient();
}
}
In our case, EKMSClientSdkConfiguration bean is not getting created and the #PostConstruct is also not getting executed.
I went through the Spring Boot 2.2.RELEASE notes which is pointing to Spring Framework 5.2 upgrade guide. Here, I learned that spring boot 2.2.0 RELEASE is using Spring framework 5.2. In Spring framework 5.2, we have many changes.
It looks like this is the root cause of bean not getting loaded, but I am not sure about it.
Any help will be appreciated. Let me know if additional information is needed.
I found spring.main.lazy-initialization=true property in my application which was causing the above issue. When I removed it from the application.properties, This issue is resolved. This is the major change which was introduced in 2.2.0.RELEASE of spring boot

Spring Boot Reactive WebClient "serverWebExchange must be null" when Spring Security OAuth is in use

I would like to use a WebClient from a Spring Boot WebFlux app that is set up with Spring Security OAuth 2 Client Credentials.
But, I get: java.lang.IllegalArgumentException: serverWebExchange must be null
The code is here: https://github.com/mparaz/spring-apigee-client
When I disable Spring Security by removing it from the pom.xml, it works properly.
When I keep using Spring Security, but instead of returning the webClient() chain result to the controller, and just prints it out, it also works.
It looks like the Reactive client and server don't work together when Spring Security is used. How could I get them running together?
For me the problem was following
https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#oauth2Client-authorized-manager-provider
The DefaultOAuth2AuthorizedClientManager is designed to be used within the context of a HttpServletRequest. When operating outside of a HttpServletRequest context, use AuthorizedClientServiceOAuth2AuthorizedClientManager instead.
Comment on the following link worked for me
https://www.gitmemory.com/issue/spring-projects/spring-security/8444/621567261
Another link
https://github.com/spring-projects/spring-security/issues/8230
Comment
DefaultReactiveOAuth2AuthorizedClientManager is intended to be used within a request context.
Given that you're seeing serverWebExchange cannot be null, you must be operating outside of a request context, which in case you should use AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager instead.
NOTE: Change the ServerOAuth2AuthorizedClientRepository parameter to ReactiveOAuth2AuthorizedClientService.
Actual code
#Bean
fun serverOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations: List<ClientRegistration>)
: ServerOAuth2AuthorizedClientExchangeFilterFunction {
val clientRegistrationRepository = InMemoryReactiveClientRegistrationRepository(clientRegistrations)
val authorizedClientService = InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository)
val oAuth2AuthorizedClientManager = AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository,
authorizedClientService
)
val filterFunction = ServerOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager)
filterFunction.setDefaultClientRegistrationId(clientId)
return filterFunction
}
It seems that if you use an UnAuthenticatedServerOAuth2AuthorizedClientRepository it will propagate the webExchange from the source request going into to your #RestController into the WebClient you are using to invoke the other service causing the java.lang.IllegalArgumentException: serverWebExchange must be null
To fix this, use the autowired implementation of the ServerOAuth2AuthorizedClientRepository (this happens to be AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository)
#Bean
#LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder(ReactiveClientRegistrationRepository clientRegistrations,
ObjectMapper objectMapper,
ServerOAuth2AuthorizedClientRepository clientRepository) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2ClientFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations,
clientRepository);
oauth2ClientFilter.setDefaultClientRegistrationId("apigee");
WebClient.Builder builder = WebClient.builder();
builder.defaultHeader("Content-Type", MediaType.APPLICATION_JSON.toString());
builder.defaultHeader("Accept", MediaType.APPLICATION_JSON.toString());
builder.filter(oauth2ClientFilter);
return builder;
}

ResourceServerTokenServicesConfiguration disappeared in Spring Boot 2.0.0.M7

I have a Spring Boot application using OAuth2 and working successfully in Spring Boot 2.0.0.M2 I switched Spring Boot version to 2.0.0.M7 and the application stop working.
After some debugging, I found that the class 'org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration' is removed from the artifact 'spring-boot-autoconfigure' in 2.0.0.M7 which was doing the following initialisation...
#Bean
#ConditionalOnMissingBean(ResourceServerTokenServices.class)
public UserInfoTokenServices userInfoTokenServices() {
UserInfoTokenServices services = new UserInfoTokenServices(
this.sso.getUserInfoUri(), this.sso.getClientId());
services.setRestTemplate(this.restTemplate);
services.setTokenType(this.sso.getTokenType());
if (this.authoritiesExtractor != null) {
services.setAuthoritiesExtractor(this.authoritiesExtractor);
}
if (this.principalExtractor != null) {
services.setPrincipalExtractor(this.principalExtractor);
}
return services;
}
Now that this class removed, no initialization occurs and 'DefaultTokenServices' initialized in the class 'org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer' and my application fails.
private ResourceServerTokenServices tokenServices(HttpSecurity http) {
if (resourceTokenServices != null) {
return resourceTokenServices;
}
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetails());
this.resourceTokenServices = tokenServices;
return tokenServices;
}
Does anybody knows why this class is removed or is there any replacement for it?
Thx for answers...
It seems auto-configure delegate these configuration to Spring Security 5 until that is ready they provide a temporary jar file fulfilling the old functionality which can be reach with the following issue...
https://github.com/spring-projects/spring-security-oauth/issues/1240

Spring Boot + Mybatis #MapperScan and SqlSessionFactory

Im developing a new app using Spring Boot. I use Mybatis for persistance. Im using Java Config for everything I can.
I'm getting this exception when the app starts regarding creating my Mybatis mapper interface
exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
My Sring Boot application class is set up like this
#SpringBootApplication
#MapperScan("com.mydomain.admin.service.dao")
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
The Mybatis mapper interface class is set up like this
package com.mydomain.admin.service.dao;
public interface AdminClientDAO {
#Select("SELECT clientId, name, enabledFlag as enabled, dateAdded, dateUpdated as updateDate FROM client")
public List<Client> findAll();
}
my datasource is configured with spring boot. I've named the properties
spring.datasource.* so spring boot with auto-configure the data source
Now, Im wondering if Im assuming too much spring boot magic. I assumed that spring boot would configure the sqlSessionFactory because mybatis was in the classpath..
Many examples I see show configuring the sqlSessionFactory as a #Bean in the Java Config.. Is this the way it should be done is should spring boot be doing some magic and auto-config it?
I found my issue. I was missing mybatis-spring-boot-starter
I have
#Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
return sessionFactory.getObject();
}
In class called Application.java which extends
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
And my Application.java is initialized in class which extends
org.springframework.boot.context.web.SpringBootServletInitializer
And the datasource works fine in my Spring-Boot Application.
Hope this helps somebody searching for Spring Boot, Mybatis and SQLSessionFactory with datasource in spring.datasource.*

Error enabling OAuth2

I am new to Spring Boot and trying to work with some of the example apps from Josh Long and Dave Syer.
I have the following code :
#SpringBootApplication
#EnableOAuth2Resource
#RestController
public class SsoResourceApplication {
#RequestMapping("/hi")
public Map<String, Object> hi(Principal principal) {
System.out.println("received request from " + principal.getName());
Map<String, Object> result = new HashMap<>();
result.put("id", UUID.randomUUID().toString());
result.put("content", "Hello, world!");
return result;
}
With the dependencies defined so
compile('org.springframework.security.oauth:spring-security-oauth2:2.0.8.RELEASE.jar')
compile('org.springframework.cloud:spring-cloud-starter-security:1.0.4.RELEASE')
When I start up I get the following error
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration':
Injection of autowired dependencies failed
Thanks in advance
It looks like you omitted the property spring.oauth2.resource.userInfoUri in your application.properties (or application.yml). This property must point to a URI within your authorization server. Here is a Spring boot 1.2 to 1.3 migration document.
I assume you have an authorization server in your environment, so that the user Info URI can point to.
You also migh want to have a look at the Spring boot OAuth2 tutorial.
Finally, you would see that most recent examples use #EnableResourceServer rather than #EnableOAuth2Resource. They are equivalent, but the former does not require a dependency on spring cloud and the configuration property is slightly different (security.oauth2.resource.userInfoUri). It's all explained in the Spring boot 1.2 to 1.3 migration document.

Resources