Dropwizard application integration test, DropwizardAppRule port is null - dropwizard

I am fairly new to Dropwzard so feel free to guide me incase I am not doing something right. Here is my scenario.
I am writing an integration test for the whole application (Which runs okay) following a tutorial from a book. However my test runs but not the full app on the specified port. Below is my test
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import demo.basicapi.configuration.BasicConfiguration;
import demo.basicapi.domain.Contact;
import io.dropwizard.testing.junit.DropwizardAppRule;
import junit.framework.TestCase;
public class AppTest extends TestCase {
private Client client;
private Contact dummyClient = new Contact(0, "Jane", "Doe", "+987654321");
#ClassRule
public static final DropwizardAppRule<BasicConfiguration> RULE = new DropwizardAppRule<BasicConfiguration>(
App.class, "config.yaml");
#Before
public void setUp() {
client = ClientBuilder.newBuilder().build();
// Set the credentials to be used by the client
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("admin", "password");
client.register(feature);
}
#Test
public void testcreateAndRetrieveContact() {
// Create a new contact by performing the appropriate http request (POST)
WebTarget target = client.target(String.format("http://localhost:%d/contact", RULE.getLocalPort()));
Response response = target.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(dummyClient, MediaType.APPLICATION_JSON));
// Check that the response has the appropriate response code (201)
assertEquals(response.getStatus(), 201);
}
}
However when I run the test, I get a Null pointer exception when retrieving the port number
RULE.getLocalPort() // This returns null in my test.
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.274 sec <<< FAILURE!
testcreateAndRetrieveContact(demo.basicapi.AppTest) Time elapsed: 0.132 sec <<< ERROR!
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at io.dropwizard.testing.DropwizardTestSupport.getLocalPort(DropwizardTestSupport.java:249)
at io.dropwizard.testing.junit.DropwizardAppRule.getLocalPort(DropwizardAppRule.java:180)
at demo.basicapi.AppTest.testcreateAndRetrieveContact(AppTest.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Also, I am a bit concerned that if I play around with this line, I dont get any error whatsoever, It doesn't matter the name of config file,
#ClassRule
public static final DropwizardAppRule<BasicConfiguration> RULE = new DropwizardAppRule<BasicConfiguration>(
App.class, "config.yaml");
Changing the name of the .yaml file to something nonexisted does not throw any other error in the tests.
I am using Dropwizard version 1.3.12, Is there anything I could change to be succesful. I for now I am not focussing on separate representation tests, but feel free to advise. Thanks.
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-testing</artifactId>
<version>1.3.12</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

Related

How to view a FileUpload response body as an upload button when seen through Swagger UI

I'm working on building a Quarkus REST API for uploading files and I'd like to use the Swagger UI while developing to have a tight feedback loop as I develop the site. However I'm struggling to get Swagger UI to format the file input elegantly.
I've tried to follow the RESTEasy Reactive guide for instruction on how to accept a file as a response body for a route but I can't seem to get Swagger UI to display the input as anything but a large text field. Here is the Quarkus 2.14 example as seen through the Swagger UI.
While developing APIs before I've grown familiar with a file upload prompt in the Swagger UI as shown here in Swagger docs. The file upload prompt allows an end user to select any arbitrary file (binary or text) to upload. I'd expect I should be able to convey to Swagger UI that I'd like this field treated as a file instead of text.
Is this a bug or do I need some extra metadata to pick a more appropriate view for this API's inputs?
Details to reproduce
I'm using Quarkus 2.14 and am able to reproduce the issue simply using the example found in the Quarkus RESTEasy guide.
Quarkus Extensions:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-swagger-ui</artifactId>
</dependency>
RESTEasy Route:
package com.me.example;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jboss.resteasy.reactive.PartType;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;
#Path("/files")
#RequestScoped
public class ExampleResource {
public static class Person {
public String firstName;
public String lastName;
}
#POST
public void multipart(#RestForm String description,
#RestForm("image") FileUpload file,
#RestForm #PartType(MediaType.APPLICATION_JSON) Person person) {
}
}
Rendered OpenAPI document:
---
openapi: 3.0.3
info:
title: API
version: 0.1.0-SNAPSHOT
paths:
/files:
post:
tags:
- Example Resource
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
description:
type: string
image:
$ref: '#/components/schemas/FileUpload'
person:
$ref: '#/components/schemas/Person'
encoding:
person:
contentType: application/json
responses:
"201":
description: Created
components:
schemas:
FileUpload:
type: object
Person:
type: object
properties:
firstName:
type: string
lastName:
type: string
Helen found a relevant Quarkus issue that helped identify a workaround to my issue. With some modifications I was able to get a single file to upload while maintaining the intuitive file picker interface in Swagger UI.
package com.me.example;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;
#Path("/files")
#RequestScoped
public class ExampleResource {
#Schema(type = SchemaType.STRING, format = "binary")
public static class UploadItemSchema {
}
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void multipart(#RestForm("image") #Schema(implementation = UploadItemSchema.class) FileUpload file) {
}
}

Spring cloud contract stub jar as a http rest endpoint

I'm trying to setup Spring contract stub jar as either a fat jar with consumer or a http REST endpoint that my services can send request to and eventually receive the evaluated response.
Ideally I'd prefer the latter where consumer could run the stub to manage the interactions. My tests from consumer to local producer stubs work as expected. My compilation fails when I add the required annotations to the main class for stub runner. I think I'm missing some config or setup needed for the consumer to run the stub either as http REST endpoint or recognize within its m2.
The app compilation fails with #EnableStubRunnerServer complaining the below:
ConsumerApplication.java:[8,60] package org.springframework.cloud.contract.stubrunner.server does not exist
ConsumerApplication.java:[15,2] cannot find symbol
[ERROR] symbol: class EnableStubRunnerServer
ConsumerApplication.java:
#SpringBootApplication
#EnableWebMvc
#EnableStubRunnerServer
#Slf4j
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
application.properties (Consumer):
stubrunner.ids=com.somecompany.somegroup:producer:0.0.1-SNAPSHOT:stubs:8081
stubrunner.stubsMode=REMOTE
server.ssl.key-store-password=password
server.ssl.key-password=password
server.ssl.trust-store-password=password
server.port=8081
Test.java: - This test works
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
#AutoConfigureMockMvc
#AutoConfigureJsonTesters
#AutoConfigureStubRunner( ids = "com.somecompany.somegroup:producer:+:stubs:8081",
stubsMode = StubRunnerProperties.StubsMode.LOCAL)
#DirtiesContext
public class ContractControllerTest extends AbstractTest {
}
pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
Since you're trying to add test code to your main, production code, you have to change
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
to
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
</dependency>

Ribbon Retry properties not respected

I have a zuul gateway application, that receives requests from a client app and forwards the requests using load balanced rest template to a micro service with 2 endpoints, say endpoint1 and endpoint2 (load balancing between the two end points in round robbin which is okay for now, although I want it to be availability based).
Here are the issues I am facing -
I brought down one of the end points, say endpoint2 and tried calling the zuul route and I see that when the request is going to the endpoint2 - zuul takes 2 mins or so before failing with HTTP 503 and does not retry on the next request. the error is just cascaded back to the caller.
Also, even after setting the read time out and connect timeout configurations, I don't see ribbon respecting the configuration and still takes 2 mins to throw the error from the server.
I tried enabling logs at the netflix package level, but I am unable to see logs unless I pass a custom http client to rest template.
I am new to netflix stack of components... please advise if I am missing something obvious. Thanks
<?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.mycomp</groupId>
<artifactId>zuul-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zuul-gateway</name>
<description>Spring Boot Zuul</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>Edgware.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-lambda</artifactId>
<version>1.11.242</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.10</version>
</dependency>
<dependency>
<groupId>com.netflix.netflix-commons</groupId>
<artifactId>netflix-commons-util</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
and my application.yml looks like below -
eureka:
client:
healthcheck:
enabled: true
lease:
duration: 5
service-url:
defaultZone: http://localhost:8761/eureka/
ingestWithOutEureka:
ribbon:
eureka:
enabled: false
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: http://demo-nlb-6a67d59c901ecd128.elb.us-west-2.amazonaws.com,http://demo-nlb-124321w2a123ecd128.elb.us-west-2.amazonaws.com
okToRetryOnAllOperations: true
ConnectTimeout: 500
ReadTimeout: 1000
MaxAutoRetries: 5
MaxAutoRetriesNextServer: 5
MaxTotalHttpConnections: 500
MaxConnectionsPerHost: 100
retryableStatusCodes: 404,503
okhttp:
enabled: true
zuul:
debug:
request: true
parameter: true
ignored-services: '*'
routes:
ingestServiceELB:
path: /ingestWithoutEureka/ingest/**
retryable: true
url: http://dummyURL
management.security.enabled : false
spring:
application:
name: zuul-gateway
cloud:
loadbalancer:
retry:
enabled: true
logging:
level:
org:
apache:
http: DEBUG
com:
netflix: DEBUG
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 60000
and my application class looks like below
#SpringBootApplication
#EnableZuulProxy
#EnableDiscoveryClient
public class ZuulGatewayApplication {
#Bean
public InterceptionFilter addInterceptionFilter() {
return new InterceptionFilter();
}
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}
and lastly my zuul filter looks like below -
package com.zuulgateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.stream.Collectors;
public class InterceptionFilter extends ZuulFilter{
private static final String REQUEST_PATH = "/ingestWithoutEureka";
#LoadBalanced
#Bean
RestTemplate loadBalanced() {
//RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
#Autowired
#LoadBalanced
private RestTemplate loadBalancedRestTemplate;
#Override
public String filterType() {
return "route";
}
#Override
public int filterOrder() {
return 0;
}
#Override
public boolean shouldFilter() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String method = request.getMethod();
String requestURI = request.getRequestURI();
return requestURI.startsWith(REQUEST_PATH);
}
#Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
try {
String requestPayload = ctx.getRequest().getReader().lines().collect(Collectors.joining(System.lineSeparator()));
String response = loadBalancedRestTemplate.postForObject("http://ingestWithOutEureka/ingest", requestPayload, String.class);
ctx.setResponseStatusCode(200);
ctx.setResponseBody(response);
} catch (IOException e) {
ctx.setResponseStatusCode(500);
ctx.setResponseBody("{ \"error\" : " + e.getMessage() + " }");
System.out.println("Exception during feign call - " + e.getMessage());
e.printStackTrace();
} finally {
ctx.setSendZuulResponse(false);
ctx.getResponse().setContentType("application/json");
}
return null;
}
}
So, here are the solutions that worked for me -
Issue 1 - Retry was not working in spite of configuring ribbon.<client>.OkToRetryOnAllOperations: true. Ribbon was clearly ignoring my configuration.
Solution: - It's strange, but after some debugging I had noticed that Ribbon was picking up client level configuration only if a global configuration was present in the first place.
Once I set the global "OkToRetryOnAllOperations" as either "true" or "false" as shown below, ribbon started picking up the ribbon.<client>.OkToRetryOnAllOperations as expected and I could see the retries happening.
ribbon:
OkToRetryOnAllOperations: false
Issue 2 - Also, even after setting the read time out and connect timeout configurations, I don't see ribbon respecting the configuration and still takes 2 mins to throw the error from the server
Solution 2 - Though ribbon started retrying requests after the changes suggested in solution 1 above, I did not see ribbon honoring <client>.ribbon.ReadTimeout and <client>.ribbon.ConnectTimeout.
After spending some time, I figure that this is because of using RestTemplate.
While spring documentation mentions that you could use load balanced RestTemplate for achieving retries, it does not mention that the timeouts wont work with it. Based on this SO answer from 2014, it looks like while ribbon has been added as a interceptor when using load balanced RestTemplate to achieve serviceId to URI resolution, ribbon does not use the underlying HTTP client and uses the http client provided by the RestTemplate. Thus, the ribbon specific <client>.ribbon.ReadTimeout and <client>.ribbon.ConnectTimeout are NOT honored. After I added timeouts to RestTemplate, requests have started timing out at expected intervals.
Lastly,
Issue 3 - I enabled logs by passing a custom http client to rest template.
#LoadBalanced
#Bean
RestTemplate loadBalanced() {
RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
System.out.println("returning load balanced rest client");
((HttpComponentsClientHttpRequestFactory)restTemplate.getRequestFactory()).setReadTimeout(1000*30);
((HttpComponentsClientHttpRequestFactory)restTemplate.getRequestFactory()).setConnectTimeout(1000*3);
((HttpComponentsClientHttpRequestFactory)restTemplate.getRequestFactory()).setConnectionRequestTimeout(1000*3);
return restTemplate;
}
#Bean
LoadBalancedBackOffPolicyFactory backOffPolicyFactory() {
return new LoadBalancedBackOffPolicyFactory() {
#Override
public BackOffPolicy createBackOffPolicy(String service) {
return new ExponentialBackOffPolicy();
}
};
}
With all the changes I see that the request retries are happening and with the timeouts and with exponential backoff and with request / responses logs visible as expected. Good luck!

How to configure the Neo4j repository with Spring Data Neo4j 3.4.0?

I tried to upgrade from the 3.3.2 to the 3.4.0 version of spring data neo4j on search.maven.org but the build now gives the following exception:
AnnotationFormatError: Invalid default: public abstract java.lang.Class org.springframework.data.neo4j.config.EnableNeo4jRepositories.repositoryBaseClass()
The application works just fine in 3.3.2.
Here is the configuration class:
#Configuration
#EnableNeo4jRepositories(basePackages = { "it.data.neo4j.repository" })
#EnableTransactionManagement
#ComponentScan(basePackages = { "it.data.neo4j.service" })
public class Neo4JRepositoryConfiguration extends Neo4jConfiguration {
private static Logger logger = LoggerFactory.getLogger(Neo4JRepositoryConfiguration.class);
public static final String URL = "http://localhost:7474/db/data/";
public static final String LOGIN = "neo4j";
public static final String PASSWORD = "xxxx";
Neo4JRepositoryConfiguration() {
setBasePackage("it.data.neo4j.domain");
}
#Bean
GraphDatabaseService graphDatabaseService() {
return new SpringCypherRestGraphDatabase(URL, LOGIN, PASSWORD);
}
#Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory;
#Override
public PlatformTransactionManager neo4jTransactionManager(
GraphDatabaseService graphDatabaseService) {
return new ChainedTransactionManager(
new JpaTransactionManager(entityManagerFactory.getObject()),
new JtaTransactionManagerFactoryBean(graphDatabaseService).getObject());
}
}
The dependencies are:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>3.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>3.4.0.RELEASE</version>
</dependency>
Most likely a conflicting class path dependencies with spring-data-commons.jar
Make sure all jars on the class path are using the same version of spring-data-commons.
In my case I had 2 jars referencing both spring-data-commons.jar 1.10 and 1.11 which caused the issue.
Does your package it.data.neo4j.repository contain both JPA and Neo4j repositories? If so you may need to segregate them into separate packages.
Additionally, Spring Data Neo4j version 4 is a major shift from the previous versions and a bit of code migration is involved, it is possible your actual application code needs to be adjusted to be compatible with SDN4:
http://docs.spring.io/spring-data/neo4j/docs/4.0.0.RELEASE/reference/html/#migration

Spring boot Security Disable security

When I use security.basic.enabled=false to disable security on a Spring Boot project that has the following dependencies:
<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-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
I see the following Exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration$ManagementWebSecurityConfigurerAdapter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
In order to fix this exception I had to add the property - management.security.enabled=false . My understanding is that when the actuator is in the classpath, both security.basic.enabled=false and management.security.enabled=false should be set to disable the security.
Could someone please let me know if my understanding is wrong?
In case you have spring-boot-actuator in your package, you should add the following
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration.class})
With older Spring-boot, the class was called ManagementSecurityAutoConfiguration.
In newer versions this has changed to
#SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class}
)
UPDATE
If for reactive application you are having the same issue, you can exclude the following classes
#SpringBootApplication(exclude = {ReactiveSecurityAutoConfiguration.class, ReactiveManagementWebSecurityAutoConfiguration.class })
What also seems to work fine is creating a file application-dev.properties that contains:
security.basic.enabled=false
management.security.enabled=false
If you then start your Spring Boot app with the dev profile, you don't need to log on.
For Spring Boot 2 following properties are deprecated in application.yml configuration
security.basic.enabled: false
management.security.enabled: false
To disable security for Sprint Boot 2 Basic + Actuator Security following properties can be used in application.yml file instead of annotation based exclusion
(#EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class}))
spring:
autoconfigure:
exclude[0]: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
exclude[1]: org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
For application.properties syntax would be like
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
If you need security as a dependency but don't want Spring Boot to configure it for you, you can use this exclusion:
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class
})
For the spring boot 2 users it has to be
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
Step 1: Comment annotation #EnableWebSecurity in your security config
//#EnableWebSecurity
Step 2: Add this to your application.properties file.
security.ignored=/**
spring.security.enabled=false
management.security.enabled=false
security.basic.enabled=false
For more details look here: http://codelocation.com/how-to-turn-on-and-off-spring-security-in-spring-boot-application/
Add following class into your code
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;
/**
* #author vaquar khan
*/
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated().and().csrf().disable();
}
}
And insie of application.properties add
security.ignored=/**
security.basic.enabled=false
management.security.enabled=false
Answer is to allow all requests in WebSecurityConfigurerAdapter as below.
you can do this in existing class or in new class.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
}
Please note : If ther is existing GlobalMethodSecurityConfiguration class, you must disable it.
If you are using #WebMvcTest annotation in your test class
#EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })
#TestPropertySource(properties = {"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration"})
doesn't help you.
You can disable security here
#WebMvcTest(secure = false)
The easiest way for Spring Boot 2 without dependencies or code changes is just:
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
Permit access to everything using antMatchers("/")
protected void configure(HttpSecurity http) throws Exception {
System.out.println("configure");
http.csrf().disable();
http.authorizeRequests().antMatchers("/").permitAll();
}
I simply added security.ignored=/**in the application.properties,and that did the charm.
The only thing that worked for me:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().permitAll();
}
and
security.ignored=/**
Could be that the properties part is redundant or can be done in code, but had no time to experiment. Anyway is temporary.
You need to add this entry to application.properties to bypass Springboot Default Security
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
Then there won't be any authentication box.
otrws, credentials are:-
user and 99b962fa-1848-4201-ae67-580bdeae87e9 (password randomly generated)
Note: my springBootVersion = '1.5.14.RELEASE'
You can configure to toggle spring security in your project by following below 2 steps:
STEP 1:
Add a #ConditionalOnProperty annotation on top of your SecurityConfig class. Refer below:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity (prePostEnabled = true)
#ConditionalOnProperty (name = "myproject.security.enabled", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// your security config
}
STEP 2:
Add following config to your application.properties or application.yml file.
application.properties
security.ignored=/**
myproject.security.enabled=false
OR
application.yml
security:
ignored: /**
myproject:
security:
enabled: false
In order to avoid security you can use annotations.
Use this annotation on top of configure class:
#EnableWebSecurity
For example:
#EnableWebSecurity
#Configuration
public class AuthFilter{
// configured method
}
As previously multiple solutions mentioned to disable security through commenting of
#EnableWebSecurity
annotation and other is through properties in application.properties or yml. But those properties are showing as deprecated in latest spring boot version.
So, I would like to share another approach to configure default username and password in your application-dev.properties or application-dev.yml and use them to login into swagger and etc in development environment.
spring.security.user.name=admin
spring.security.user.password=admin
So, this approach will also provides you some kind of security as well and you can share this information with your development team. You can also configure user roles as well, but its not required in development level.
Latest spring 2.7.x, create two class, set DISABLE_KEYCLOAK_AUDIT_PROPERTY = 'your key' in application profile for enable/disable security:
public static final String DISABLE_KEYCLOAK_AUDIT_PROPERTY = "enable_security";
#EnableAutoConfiguration(exclude =
{org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class
})
#Configuration
#ConditionalOnProperty(name = DISABLE_KEYCLOAK_AUDIT_PROPERTY, havingValue = "true")
static
class DisableSecurityConfig {
}
#Configuration
#ConditionalOnProperty(name = DISABLE_KEYCLOAK_AUDIT_PROPERTY, havingValue = "false")
#Import({KeycloakSecurityConfig.class, KeycloakConfig.class})
static
class EnableSecurityConfig {
}
for example use in application.yml:
enable_security: true
Add the below lines to your main app.
Remove org.activiti.spring.boot.SecurityAutoConfiguration.class if you're not using activiti.
Similarly, remove the one for actuator if you're not using spring-boot-actuator.
#EnableAutoConfiguration(exclude = {
org.activiti.spring.boot.SecurityAutoConfiguration.class,
org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class })
With Gradle and Spring boot v2.4.4, you can exclude spring security completely by adding this config in your build.gradle
configurations.all {
exclude group:"org.springframework.boot", module: "spring-boot-starter-security"
}
As of Spring Boot 2.7.3 using #EnableAutoConfiguration(exclude = {}) generated an error, suggesting the exclude property be used in the #SpringBootApplication annotation.
Here is what worked for me when disabling Spring Security completely.
#SpringBootApplication(
exclude = {
SecurityAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class
})
public class GeoServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GeoServiceApplication.class, args);
}
}
I tried excluding only SecurityAutoConfiguration.class, but I got an error for no HttpSecurity bean defined for ManagementWebSecurityAutoConfiguration.class.
With Spring 2.6.0 this helped in my case:
#EnableAutoConfiguration(exclude = {
org.springframework.boot.autoconfigure.security.SecurityDataConfiguration.class
})
And additional I had to remove the dependency in the pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
In Spring Security 5.7.0-M2 WebSecurityConfigurerAdapter was deprecated. Spring Security team encourages users to move towards a component-based security configuration.
package com.may.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll(); // config to permit all requests
return http.build();
}
#Bean
public AuthenticationManager authenticationManager() { // to delete default username and password that is printed in the log every time, you can provide here any auth manager (InMemoryAuthenticationManager, etc) as you need
return authentication -> {
throw new UnsupportedOperationException();
};
}
}
More examples here:
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
I added below settings in application.yml and worked fine.
security:
route-patterns-to-be-skipped:
- /**/*
this can be converted as security.route-paterns-to-be-skipped=/**/* for application.properties

Resources