java Spring Boot with Swagger - Failed to load remote configuration - java

I have a Java 11 Spring Boot 2.5.1 application.
Swagger works locally via http:
I have added Swagger, which works perfectly on my localhost:
http://localhost:8085/swagger-ui/index.html#/
Swagger does not work remotely via https:
However, when I deploy it to a remote server, I get the following error:
https://mycompany.co/pow-wow/swagger-ui/index.html#/
Error
Failed to load remote configuration.
note: the remote server is accessed via https.
The REST endpoints are accessible on the remote server.
e.g. GET https://mycompany.co/pow-wow/powwow/test-me returns a 200 as expected.
Question
How do I access the Swagger via the remote server?
Code
pom.xml
<!-- Swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.7</version>
</dependency>
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().disable().authorizeRequests().antMatchers("/powwow/*").hasRole("USER").and().httpBasic();
//http.csrf().disable().authorizeRequests().antMatchers("/*").permitAll().and().httpBasic();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/soapWS/**").permitAll().and()
.authorizeRequests().antMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll().and()
.authorizeRequests().antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated().and()
.httpBasic().and()
.csrf().disable();
}
}
More info:
When looking at the network traffic in the browser when accessing Swagger.
Locally, there is a call to:
http://localhost:8085/v3/api-docs/swagger-config
returns:
{"configUrl":"/v3/api-docs/swagger-config","oauth2RedirectUrl":"http://localhost:8085/swagger-ui/oauth2-redirect.html","url":"/v3/api-docs","validatorUrl":""}
Remotely, there is a call to:
https://mycompany.co/v3/api-docs/swagger-config
which returns a 302.
But https://mycompany.co/pow-wow/v3/api-docs/swagger-config
returns:
{"configUrl":"/v3/api-docs/swagger-config","oauth2RedirectUrl":"http://localhost:8085/swagger-ui/oauth2-redirect.html","url":"/v3/api-docs","validatorUrl":""}
So this suggests the issue is related to the /pow-wow context path is missing in the call.

You should try and add
springdoc:
swagger-ui:
config-url: /pow-wow/v3/api-docs/swagger-config
url: /v3/api-docs
to your application.properties. In your provided example
https://mycompany.co/pow-wow/v3/api-docs/swagger-config
it shows that you have "/pow-wow/" in your path. Swagger needs to know where to fetch its config.

Try to add this as well to your security config class
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui/**", "/v3/api-docs/**");
}

I had the same issue :
with mvn spring-boot:run : OK
on my local Tomcat server : OK
on the Tomcat server of my organization : KO (Failed to load remote configuration)
The cause was the reverse proxy of my organization that blocked the loop-back call of the application.

To those who are asking:
I had the same issue and this video helped me check it out: https://www.youtube.com/watch?v=A_RWUcTqHBI
Just simple step by step.
Regarding my project to be on the same page:
Spring Boot 3 + Spring Security.
So I:
Added "/swagger-ui/" and "/v3/api-docs/" as #Mohamed suggested to my SecurityFilterChain bean.
Added springdoc-openapi-starter-webmvc-ui dependency in POM.
Configurated SwaggerConfig as follow:
#Configuration
#OpenAPIDefinition
public class SwaggerConfig {
#Bean
public OpenAPI config() {
return new OpenAPI().info(
new Info()
.title("")
.version("")
.description("")
);
}
}
http://localhost:8080/swagger-ui/index.html#/
And it worked smoothly!

Config that helped me:
springdoc:
swagger-ui:
configUrl: /your-service/v3/api-docs/swagger-config
url: /your-service/v3/api-docs
If you have problems with the try it out block (404 error, wrong url), then just use the #OpenAPIDefinition annotation. Kotlin example:
#SpringBootApplication
#OpenAPIDefinition(
info = Info(title = "Your Service API", version = "1.0", description = "Your service description"),
servers = [Server(url = "/your-service", description = "Your Service")]
)

If security config allow swagger, it's because of cashing, try it after clear browser cash or in browser incognito mode.

Related

Spring security clashes with the POST method

I am trying to implement Spring basic auth into the app. I added the folowing lines to application.properties:
#Security
security:
user:
name: admin
password: admin
So the Spring will create a web security config bean by itself. But I ran some tests and everything works as expected for any method besides POST as it throws 403 status. I browsed the web and discovered that it happens due to csrf protection and I disabled it, creating additional web security config class:
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
return http.build();
}
}
However, it completely disables the authentication. The user does not need a password and a login to use the resources.
My question is, how do I configure the authentication in a way POST method will not throw 403? Do I need to write a full web security config and delete those 4 lines from application.properties or there is an alternative way? Thanks in advance.

Spring boot blocked by cors when running on aws fargate but not locally

this is my very first post so forgive me if i do not include all the proper information you need to help me.
I created a spring boot backend server Rest API that uses spring security. When i call this api through my react project, i initially got a 500 status response telling me that the request has been blocked be CORS. I solved is issue though with the following corsConfig file:
#Configuration
public class CorsConfig {
#Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowedOrigins("*");
}
};
}
}
And when i run the react project(localhost:3000) and the spring api(localhost:8080) everything runs fine. I can even see from the headers that it returns "Access-Control-Allow-Origin: *".
Below is also my spring security configurations:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and();
http.csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.cors();
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
The issue i am having is that i have now deployed my spring boot api on a docker container running on aws ecs fargate, and i now get the 500 status response again and i can also see that the header "Access-Control-Allow-Origin: *" is no longer present in the response.
So to quickly sum up. Everything works fine locally, the issue is only there when i call my backend api running AWS.
I have also tried using #CrossOrigin(origins = "*") on my restController class.
I have found similar issues out there, but they all seem to be when people are running their applications locally, and has been fixed by the solutions i have already used.
It seems to me that this issue is related to AWS somehow, but i am not sure.
I hope someone can point me in the right directions here, and please let me know if i need to provide more screenshots of something. Thank you.
sometime other Internal Server Error hidden behind CROS, please try to check the application logs,if possible redirect them to cloudWatch logs.
I doubt Access-Control-Allow-Origin is causing your 500 errors, it's not the main source of the problem, some other part of your code cause the issue.

Spring Boot OAuth2, with Tomcat and nginx get error ERR_TOO_MANY_REDIRECTS after authenticate

I have a Spring Boot application, it use OAuth2 authentication from WSO2 Identity Server.
When I run the aplication on Spring Tool Suit, it works, so i can sing in and use my web site.
But when I run my application on Tomcat(9.0), I try access a page, and redirect to login page, and when i try to sign in, I get the error ERR_TOO_MANY_REDIRECTS
Error Example: When my spring boot app is runing on Tomcat, and I try to access the html page: https://domain/chat/example.html
if the user was not authenticated,
redirects to login page WSO2 Identity Server:
https://domain/is/authenticationendpoint/login.do
after login, the page redirects to the urls below, and does not redirect to url(https://domain/chat/example.html)
https://domain/is/oauth2/authorize
https://domain/chat/oauth2/authorization/wso2
https://domain/chat/login/oauth2/code/wso2
https://domain/chat/login
These pages return the error ERR_TOO_MANY_REDIRECTS.
A user can authenticate, but the application redirect and go to a loop that causes the error, the loop is between the urls 1,2,3,4.
Tomcat Log
Spring Boot Configurations:
LoginController.java
#Controller
public class LoginController {
#GetMapping("/oauth-login")
public String getLoginPage(Model model) {
return "redirect:/oauth2/authorization/wso2";
}
}
ConfigSecurity.java
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)//abilitar seguranca nos metodos
public class ConfigSecurity extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth-login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login().loginPage("/oauth-login")
.and()
.logout().logoutUrl("/applogout");
}
}
application.properties
server.port=8443
spring.security.oauth2.client.registration.wso2.client-name=WSO2 Identity Server
spring.security.oauth2.client.registration.wso2.client-id=asdasd
spring.security.oauth2.client.registration.wso2.client-secret=asdasd
spring.security.oauth2.client.registration.wso2.redirect-uri=https://domain/chat/login/oauth2/code/wso2
spring.security.oauth2.client.registration.wso2.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.wso2.scope=openid
#Identity Server Properties
spring.security.oauth2.client.provider.wso2.authorization-uri=https://domain/is/oauth2/authorize
spring.security.oauth2.client.provider.wso2.token-uri=https://domain/is/oauth2/token
spring.security.oauth2.client.provider.wso2.user-info-uri=https://domain/is/oauth2/userinfo
spring.security.oauth2.client.provider.wso2.jwk-set-uri=https://domain/is/oauth2/jwks
This is my git: https://github.com/Mingato/Root2
I followed the tutorial: https://medium.com/#piraveenaparalogarajah/secure-your-spring-boot-application-with-wso2-identity-server-8140af8aa30b
When I run a .jar file it works but when I run a .war file on tomcat it does not work.
After many researchs, i found my mistake. My Configurations is right, but when i run my Spring boot app on Tomcat, i have to configure my application to run on it, but there are another way, I run my app in the easiest way, I generate the .jat and execute with the command bellow
java -jar myapp.jar
So I remove the Tomcat Server to deploy my spring boot applications.

Vaadin 8 (withouth Spring Boot/Security) and Keycloak not working

I have a 'legacy' application build with Vaadin 8 that I need to secure with Keycloak.
Unfortunately, the redirect to Keycloak is not even triggered.
As a test, I created a Spring Boot application and tried to secure it with Keycloak without any problems, but it fails to work with Vaadin 8.
My configuration files for the Spring Boot application are;
application.properties
keycloak.realm=myrealm
keycloak.resource=test-app
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.public-client=true
keycloak.securityConstraints[0].authRoles[0]=Patient
keycloak.securityConstraints[0].authRoles[1]=Admin
keycloak.securityConstraints[0].securityCollections[0].name=boeken
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/books
keycloak.securityConstraints[1].authRoles[0]=Admin
keycloak.securityConstraints[1].securityCollections[0].name=backend
keycloak.securityConstraints[1].securityCollections[0].patterns[0]=/manager
server.port=8090
KeycloakConfig class
#Configuration
public class KeycloakConfig {
#Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Just by adding this, the Keycoal-redirect is triggered and I can log in. Easy.
What should I change/add when i'm trying to secure the Vaadin 8 application?
It's not a Spring/Spring boot-application (not started by SpringApplication.run()), I don't think it's mandatory to have a Spring/Spring boot app in order to secure it with Keycloak (correct me if i'm wrong).
The problem seems to be that the application.properties file is ignored (although it is on the class path), as I can navigate to the urls that should be secured.
Does anyone see what's missing/wrong?
In case you would consider using Spring boot, I created a working example of integration between Vaadin 8, Spring Boot and Keycloak.
It makes use of vaadin-spring-boot, keycloak-spring-boot-adapter and keycloak-spring-security-adapter plugins to get jump started and your application.properties will get picked up correctly. In essence, this setup tells Vaadin to let Spring Security handle all security, and in turn Keycloak is hooked up as the security handler.
The only configuration needed is to have a custom SecurityConfiguration to define your specific security needs.
But the bulk comes down to:
#Configuration
#EnableWebSecurity
#EnableVaadinSharedSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.formLogin().disable();
// disable spring security csrf as Vaadin already provides this
// also possible to disable this in Vaadin and leave this enabled
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/vaadinServlet/UIDL/**").permitAll()
.antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()
.anyRequest().authenticated();
http
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
http
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class);
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint());
http
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}
...
}

Static resources are secured and not accessible after migrating to Spring Boot 2.0

I have migrated a Spring Boot web application from 1.5.10 to 2.0.0, which is deployed with Heroku and runs over several domains. For the main domain, that was the first one to be set, everything is working smoothly but for the rest any of the static resources; like Javascript, CSS, images and icons (Webjars) are not accessible.
maindomain.com/js/example.js works fine and can be directly accessed with the browser. secondarydomain.com/js/example.js can't be accessed by the browser and running the app arises this error, I guess because instead of the .js file is returning some text message:
Refused to execute script from '' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled
The static resources are located at:
/resources/static/css
/resources/static/js
/resources/static/images
I have set the Spring security configuration with an extension of WebSecurityConfigurerAdapter, where I have withdrawn the annotation #EnableWebSecurity and I have added this code, with the intention to make sure that those resources are accessible, without success:
http
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
There is a HandleInterceptor, which deals with the directories accessible by each secondary domain. The main one, has access all over the application.
In this other question, with a different approach to the same problem, there is an extract of the HandleInterceptor.
Spring Boot 2.0.0 & static resources with different domains for the same app
Spring Security with boot is on the classpath, the auto-configuration secures all endpoints by default.
However, when it comes to complex applications, we need different security policies per endpoints. We also need to configure which endpoints should be secured, what type of users should be able to access the endpoints, and which endpoints should be public.
WebSecurity allow we to configure adding RequestMatcher instances that Spring Security should ignore.
HttpSecurity allow we can configure the endpoints that should be secured and the endpoint that should be public
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/image/**"").permitAll()
}
}
Hope it help.

Categories

Resources