Spring Cloud Gateway RouteLocator Java Code Can not get with specific route id - spring

I have tried to custom RouteLocator in Spring Cloud Gateway with Java Code. I can see all the list of routes that registered with endpoint /actuator/gateway/routes but when I was trying to get the specific route in given id it is 404 /actuator/gateway/routes/auth-server.
This is what I was trying to invoke /actuator/gateway/routes
[
{
"route_id": "auth-server",
"route_object": {
"predicate": "org.springframework.cloud.gateway.support.ServerWebExchangeUtils$$Lambda$264/896945135#4e9d7b14"
},
"order": 0
},
{
"route_id": "song",
"route_object": {
"predicate": "org.springframework.cloud.gateway.support.ServerWebExchangeUtils$$Lambda$264/896945135#7d49ff95"
},
"order": 0
}
]
The one with specific route /actuator/gateway/routes/auth-server
http://localhost:8080/actuator/gateway/routes/auth-server
I got the result status code 404 not found.
This is java custom route configuration:
#Configuration
public class RouteConfiguration {
#Bean
RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
return routeLocatorBuilder.routes()
.route("auth-server", predicateSpec -> predicateSpec.path("/uaa/**").uri("lb://auth-service"))
.route("song", predicateSpec -> predicateSpec.path("/song/**").uri("lb/song-service"))
.build();
}
}
It should be given with auth-server route.

#soyphea That's a known issue, but I couldn't find the ticket back on GitHub. Can you create a bug report for this just to be sure: https://github.com/spring-cloud/spring-cloud-gateway/issues/new? Thanks for your great question!

Related

Springdoc openapi migration from springfox

I am working on the migration of swagger spring fox to spring doc open api. I followed below link.
https://deepak-shinde.medium.com/migrating-from-springfox-swagger-2-to-springdoc-openapi-3-79a79757b8d1
Below version used.
spring_boot_version= "2.5.5"
springdoc_openapi_version= "1.6.0"
In gradle dependency mentioned as below
implementation "org.springdoc:springdoc-openapi-ui:$springdoc_openapi_version"
implementation "org.springdoc:springdoc-openapi-javadoc:$springdoc_openapi_version"
I defined rest controller.
#RestController
#RequestMapping("/v1")
#Slf4j
#Tag(name = "Master", description = "Master service API")
public class MasterController {
#Operation(summary = "Get test data",security = {
#SecurityRequirement(name = MasterConstant.HTTP_AUTH_SECURITY_SCHEME) }, tags = {
"Master" } ,description = " This method is used to get test data")
#PostMapping("/codes")
public ResponseEntity<MasterCodeResponse> getTestData()
}
application.properties
springdoc.swagger-ui.path=swagger-ui
springdoc.packages-to-exclude=com.master.persistence.*
springdoc.packages-to-scan=com.master.controller,com.common.controller // here * by default not working as its not listing apis
springdoc.api-docs.resolve-schema-properties=false
When i invoke v3/apidocs - Tags is coming empty. No controller name or description is displayed.
"openapi":"3.0.1",
"info":{
"title":"Test REST API",
"version":"1.0.0"
},
"servers":[
{
"url":"http://localhost:8082/master-service/",
"description":"Generated server url"
}
],
"security":[
{
"bearerAuth":[
]
}
],
"tags":[
{
}
],
Same way for operations tags is coming empty.
"/v1/codes":{
"post":{
"tags":[
null
],
"o
Below bean is defined
#Bean
public OpenAPI customizeOpenAPI() {
final String securitySchemeName = "bearerAuth";
return new OpenAPI().addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
.components(
new Components().addSecuritySchemes(securitySchemeName,
new SecurityScheme().name(securitySchemeName).type(SecurityScheme.Type.HTTP)
.scheme("bearer").bearerFormat("JWT")))
.info(new Info().title("Test REST API").version("1.0.0"));
}
Please let me know how to get the summary of the opertaion and controller tags in swagger as well as in the apidocs yaml. Please advice if i am doing something wrong here.
There were some issue about tags, as you can see here
You should try to update springdoc-openapi to at least version 1.6.7.

Spring cloud contract load active profiles

I have a contract like:
Contract.make {
ignoreForDevEnvironment() ? ignored() : ""
description ""
request {
method 'POST'
url '/something'
body($(execute("someMethod()")))
}
response {
status 200
}
}
private static Boolean ignoreForDevEnvironment() {
//read Spring Active profiles
//return true if `dev` profile is listed
}
I want my method ignoreForDevEnvironment to read the active spring profiles, how can I achieve this?

How do I create an OpenApi from a Rest interface?

I would like to map this rest interface in OpenApi?
Is there by chance a tool with which I can create an OpenApi from the rest interface without including this tool in my Spring Boot Application? Or is there a template I can use to build the interface myself in Openapi? I would be very grateful for an approach.
#GetMapping("/page")
public Page<FootballTeamLocationEntityView> getPageableFootballTeamList(#PageableDefault(value = 10) Pageable pageable) {
return footballTeamService.getFootballTeams(pageable);
}
I use OpenApi 3.0 and Spring Boot 2
UPDATE 1
default ResponseEntity<FootballTeamLocation> getPageableFootballTeamList(Pageable pageable) {
getRequest().ifPresent(request -> {
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString = "{ \"name\" : \"Westfalen-Stadion\", \"locZ\" : 5.962133212312, \"externalId\" : \"externalId\", \"locX\" : 6.02749381870403, \"id\" : 0, \"locY\" : 11.4658129805029452 }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
}
});
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
Consider using springdoc. It is a recent library that is easier to use and way less error-prone than Springfox (the other option for Spring Boot apps). We moved to it 2 years ago and we are very glad we did. There is very good documentation and tutorials online for it:
https://springdoc.org/
https://www.baeldung.com/spring-rest-openapi-documentation
It is also very active and you usually get your issues answered very fast on the github page.

Azure active directory integration angular + adal+ spring boot

I'm trying to integrate Azure active directory with an application I have. The application front end is Angular 7 and back end is Spring boot. What I did was creating a web app in Azure portal and in Angular side by using microsoft adal library get the access token then passing that token with every request and authenticate that token in the spring boot backend. What I need to know is the way I'm doing is correct ie, I'm using the same azure app credentials(Client id, Tenant id.....) in Angular and spring boot. Is we need to create different app for fronend and backend. And getting access token from front end is correct or not.
app.module.ts
-----------------
function initializer(adalService: MsAdalAngular6Service) {
return () => new Promise((resolve, reject) => {
if (adalService.isAuthenticated) {
resolve();
} else {
adalService.login();
}
});
}
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
MsAdalAngular6Module.forRoot({
tenant: 'xxxbef18-40f6-44e6-972c-407462a99xxx',
clientId: 'xxx4602f-e3c8-4114-ae23-42bf9e57dxxx',
redirectUri: 'http://localhost:4200',
navigateToLoginRequestUrl: false,
cacheLocation: 'localStorage'
})
],
providers: [ {
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [MsAdalAngular6Service]
},
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptorService,
multi: true
}],
bootstrap: [AppComponent]
})
export class AppModule { }
Filter class in backend
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AADAuthenticationFilter aadAuthFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
//allow all request access this url
http.authorizeRequests().antMatchers("/home").permitAll();
//access to this url requires authentication
http.authorizeRequests().antMatchers("/api/**").authenticated();
http.authorizeRequests().anyRequest().permitAll();
http.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class);
}
}
application.properties
# Specifies your Active Directory ID:
azure.activedirectory.tenant-id=92cbef18-40f6-44e6-972c-407462a99xxx
# Specifies your App Registration's Application ID:
spring.security.oauth2.client.registration.azure.client-id=xxx42c78-c557-48ef-8f09-be40c2093xxx
azure.activedirectory.client-id=xxx4602f-e3c8-4114-ae23-42bf9e57dxxx
# Specifies your App Registration's secret key:
spring.security.oauth2.client.registration.azure.client-secret=xxx-~H98Y68m5fFw9_P9sy-c4C4E3lAxxx
azure.activedirectory.client-secret=xxx-~H98Yxxxx5fFw9_P9sy-c4C4E3lAxxx
# Specifies the list of Active Directory groups to use for authorization:
azure.activedirectory.active-directory-groups=users
Any help would be appreciable
In theory, the access token can be obtained from the front end. From your configuration, the back end is equivalent to a resource, which is not a problem in itself, but it is generally not recommended.
As you can imagine, our general approach is to create different applications for the front end and the back end, using the front end as the web app end and the back end as the web server end, which provides access tokens.

Grails Spring Security Rest - 403 Forbidden

So I just started learning Grails, and I am trying incorporate the Spring Security REST plugin into my app, the plugin is installed in addition to spring security core which is working. In my REST client, when I hit "api/login" I am able to get an access token and it says I have the role of "ROLE_ADMIN", but then when I try to hit something using that, I keep getting a 403 Forbidden. In Postman, the REST client I am using, I have my Authorization header with "Bearer {key}", with my url of "http://localhost:8080/test/api/secret" and it gives the 403 error. I am trying to setup the log4j logging to see any other issues, but does anyone know what I should look into, any help would be appreciated. I provided my classes below if that helps, I generally used default values for everything such as the UrlMappings.
RandomController.groovy
package test
import grails.plugin.springsecurity.annotation.Secured
#Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
class MyController {
#Secured(['ROLE_ADMIN'])
def secret() {
render "You have ACCESS!!!"
}
}
Bootstrap.groovy
class BootStrap {
def init = { servletContext ->
def adminRole = new SecRole(authority: 'ROLE_ADMIN').save(flush: true)
def testUser = new SecUser(username: 'bob', password: 'test')
testUser.save(flush: true)
SecUserSecRole.create testUser, adminRole, true
}
def destroy = {
}
}
UrlMappings.groovy
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/api/$controller/$action?/$id?(.$format)?"{ constraints { // apply constraints here
} }
"/"(view:"/index")
"500"(view:'/error')
}
}
For what I can see from the code you posted, if you invoke url http://localhost:8080/test/api/secret, it should execute default action (maybe index) in SecretController but the controller you posted is called MyController.
To investigate further, you should enable more verbose logging using log4j configuration as suggested in the doc http://alvarosanchez.github.io/grails-spring-security-rest/1.5.1/docs/guide/debugging.html

Resources