Spring project with aws cognito - spring

I'm trying to use aws Cognito`s user authentication with my spring project. I configured Cognito and got a jwt token from it. When I pass the token to my api endpoint I'm getting error 401 (unauthorized).
I'm working on a ms that working in my localhost.
I saw a few examples and I feel like my application.properties is missing something but I'm not sure what.
My application properties :
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_somecode
spring.security.oauth2.client.registration.app1.client-id=my_app_id_in_cognito
My pom has the following security dependencies :
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
My configuration class :
#Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.anyRequest().authenticated().and()
.oauth2ResourceServer().jwt();
}
Tried also to change the application properties according to some spring examples :
spring.security.oauth2.client.registration.cognito.client-id=my_app_id_in_cognito
spring.security.oauth2.client.registration.cognito.client-name=app1
spring.security.oauth2.client.provider.cognito.issuer-uri=https://cognito-idp.eu-west-2.amazonaws.com/eu-west-1_somecode
but then I got the following exception because I was missing the spring.security.oauth2.resourceserver.jwt.jwk-set-uri settings in application.properties :
Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'jwtDecoderByIssuerUri' in 'OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration' not loaded because OpenID Connect Issuer URI Condition did not find issuer-uri property
- Bean method 'jwtDecoderByJwkKeySetUri' in 'OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration' not loaded because #ConditionalOnProperty (spring.security.oauth2.resourceserver.jwt.jwk-set-uri) did not find property 'spring.security.oauth2.resourceserver.jwt.jwk-set-uri'
- Bean method 'jwtDecoderByPublicKeyValue' in 'OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration' not loaded because Public Key Value Condition did not find public-key-location property
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' in your configuration.
What am I missing ?

I found this article and tried to use the same setting in the application.properties :
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://cognito-idp.{REGION}.amazonaws.com/{POOL_ID}

Related

Spring Security OAuth2 v5 : NoSuchBeanDefinitionException: 'org.springframework.security.oauth2.jwt.JwtDecoder'

I have a SpringBoot application that I am trying to update from the older Spring Security OAuth 2.x library to the newer Spring Security 5.5.x. Initially my configuration class was using the #EnableResourceServer annotation, but this was replaced with the Spring Security oauth2ResourceServer DSL method, as per the migration guide.
I have added in a custom JWT authentication converter, but am now getting the following warning on startup:
09:30:51.591 [, , ] [main] WARN %->5level org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' available
I can't see where this JwtDecoder is used in the filter chain yet, but it's stopping my application from starting up.
#Configuration
#Order(OAuthTokenApiSecurityConfig.ORDER)
public class OAuthTokenApiSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(final HttpSecurity http) throws Exception { // NOPMD
// #formatter:off
http
.requestMatcher(new OAuth2RequestMatcher())
...
...
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(customTokenAuthenticationConverter());
// #formatter:on
}
#Bean
public CustomTokenAuthenticationConverter customTokenAuthenticationConverter() {
return new CustomTokenAuthenticationConverter();
}
#Bean
public JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter() {
return new JwtGrantedAuthoritiesConverter();
}
}
dependecies {
api("org.springframework.security:spring-security-oauth2-resource-server")
api("org.springframework.security:spring-security-oauth2-core")
api("org.springframework.security:spring-security-oauth2-jose")
api("com.nimbusds:nimbus-jose-jwt")
}
springBootVersion=2.5.3
springSecurity=5.5.1
Is there some dependency that I am missing, or is there some config or something else?
The JwtDecoder is used within the Jwt Configuration to decode, and validate the incoming token against the public keys.
There's multiple ways of building the bean provided via some factory methods in the JwtDecoders class.
Specifically,
JwtDecoders.fromIssuerUri(...) and JwtDecoders.fromOidcIssuerUri(...) and I believe theres now a third method for pointing directly at a key.
The decoder it self can be explicitly set on the decoder method on the jwt configuration if you want/need to build one manually e.g. want to more add validations to the JwtDecoder.
If you read the javadoc of the OAuth2ResourceServerConfigurer there's also the option to set the Jwk Set URI via the jwkSetUri method which would also build a decoder.
The exact point the JwtDecoder is used is within the JwtAuthenticationProvider which will eventually be called from the BearerTokenAuthenticationFilter

Spring security and keyclock - ServerHttpSecurity error

I'm trying to add Spring Security to my Spring Boot application. I've created new SecurityConfig class and I've added the code below:
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
public SecurityWebFilterChain configSecurity(ServerHttpSecurity http) {
return http
.authorizeExchange(exchange -> exchange.matchers(EndpointRequest.toAnyEndpoint()).permitAll().anyExchange().authenticated())
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt)
.build();
}
}
When I try to start the application I get the error:
2021-04-08 08:58:47.828 INFO 3040 --- [ main]
o.s.s.web.DefaultSecurityFilterChain : Will secure any request
with
[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#6089c1e3,
org.springframework.security.web.context.SecurityContextPersistenceFilter#4bba628,
org.springframework.security.web.header.HeaderWriterFilter#47b4fcd5,
org.springframework.security.web.csrf.CsrfFilter#439acac0,
org.springframework.security.web.authentication.logout.LogoutFilter#6af447b6,
org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter#5679e464,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter#4420f4d4,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#517594dd,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter#67231d8d,
org.springframework.security.web.session.SessionManagementFilter#59b5251d,
org.springframework.security.web.access.ExceptionTranslationFilter#7d6b0636,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor#4b50ebea]
2021-04-08 08:58:47.883 WARN 3040 --- [ main]
ConfigServletWebServerApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'configSecurity' defined in class path
resource [it/config/SecurityConfig.class]:
Unsatisfied dependency expressed through method 'configSecurity'
parameter 0; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.security.config.web.server.ServerHttpSecurity'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
And:
APPLICATION FAILED TO START
Description: Parameter 0 of method configSecurity in
it.config.SecurityConfig required a bean of type
'org.springframework.security.config.web.server.ServerHttpSecurity'
that could not be found.
Action: Consider defining a bean of type
'org.springframework.security.config.web.server.ServerHttpSecurity' in
your configuration.
Do you know how to solve?
Below my dependecy:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-oauth2-resource-server</artifactId>
</dependency>
Try annotating the class that bean is in with the following:
#Configuration
#EnableWebSecurity
Also, make sure that bean is public - see if all of those fix it? If not - could you provide a Full Stack-Trace of the exception.
Thanks, Ben
try adding all of these annotations at the top.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
Sometimes the #EnableGlobalMethodSecurity helps
I've solved using HttpSecurity instead of ServerHttpSecurity. Below my new code:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated()).oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
}

Field properties in org.springframework.cloud.netflix.turbine.stream.TurbineStreamAutoConfiguration required a bean of type

I went through links like: Spring Boot + Eureka Server + Hystrix with Turbine: empty turbine.stream, but still did not worked for me. This question is continuation of Unable to connect to Command Metric Stream. in Hystrix Dashboard issue.
My source code: https://github.com/javaHelper/spring-cloud-cordinating-services/tree/master/Protecting-Systems-with-Circuit-Breakers
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-01-15 10:46:04.141 ERROR 4380 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field properties in org.springframework.cloud.netflix.turbine.stream.TurbineStreamAutoConfiguration required a bean of type 'org.springframework.cloud.netflix.turbine.stream.TurbineStreamProperties' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.cloud.netflix.turbine.stream.TurbineStreamProperties' in your configuration.
Simply trying to start the
turbine::
TurbineApplication.java
#SpringBootApplication
#EnableTurbine
public class TurbineApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineApplication.class, args);
}
}
application.properties
server.port=3000
spring.application.name=turbine-aggregator
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
turbine.app-config=weather-app,datetime-app
turbine.cluster-name-expression=new String("default")
remove the turbine stream dependencies from the pom.xml
That should resolve the problem.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine-stream</artifactId>
</dependency>
Maybe you need to configure Spring to enable configuration properties for turbine?
#Configuration
#EnableConfigurationProperties(TurbineStreamProperties.class)
public class TurbineConfig {
}

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.

Spring Data Rest Boot app fails to start with Java config class

I'm trying to run simple Spring Data Rest Boot app (v1.2.3.RELEASE) with only one small modification from working Spring reference example app (http://spring.io/guides/gs/accessing-mongodb-data-rest/) and it failed to start.
To be more specific when I use:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
and just following simple code configuration:
public class Application {
public static void main(String[] args){
SpringApplication.run(Config.class, args);
}
}
#SpringBootApplication
public class Config {
}
without anything else I'm getting following error on startup:
2015-04-20 12:07:32.250 ERROR 5693 --- [ main]
o.s.boot.SpringApplication : Application startup failed
org.springframework.context.ApplicationContextException: Unable to
start embedded container; nested exception is
org.springframework.boot.context.embedded.EmbeddedServletContainerException:
Unable to start embedded Tomcat ...
Caused by:
java.lang.ClassCastException:
jug.ua.json.test.Config$$EnhancerBySpringCGLIB$$79797226 cannot be
cast to
org.springframework.data.rest.core.config.RepositoryRestConfiguration
at
org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$3a999d99.config()
...
However following code configuration is working fine:
#SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
Also if instead I use:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
separate Java config class approach is working fine as well...
What I'm doing wrong, cause I can't believe I spotted such an obvious bug?
Thank you,
Oleg
The problem appears to be due to a name clash between the config bean method on SpringBootRepositoryRestMvcConfiguration (inherited from Spring Data REST's RepositoryRestMvcConfiguration) and your configuration class named Config. Renaming it to something other than Config should get things working again.

Resources