How to remove or hide the server list in Swagger UI using Springdoc? - swagger-ui

How to disable or hide the "Servers" dropdown from Swagger UI?
My Maven dependency is:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.13</version>
</dependency>

Actually I have the same problem and I found out that unfortunately it is hardcoded. The only thing you can do is overwrite url to display something else or to just be empty.
#Configuration
public class SwaggerConfig {
#Bean
public OpenAPI config() {
return new OpenAPI()
.addServersItem(serverInfo());
}
private Server serverInfo() {
return new Server()
.url("");
}
}

Related

How to display checkboxes instead of boolean in vaadin grid?

I'm trying to display my boolean values as a checkbox in a vaadin grid. I can't use the multi selection mode because i need two columns with checkboxes. The columns of the Checkboxes shell have a Caption but the Checkboxes itself shell be without a caption. Does anyone have an idea ?
I suggest to use this repo https://github.com/vaadin/grid-renderers-collection-addon. This project is developed by Vaadin devs and it provides CheckboxRenderer class. You can see it in demo but using it is very simple.
First you have to add repository and dependency into your project. In maven it looks like this:
...
<repositories>
...
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>
...
<dependencies>
...
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>grid-renderers-collection-addon</artifactId>
<version>0.94</version>
</dependency>
</dependencies>
...
Then you can use it like this:
grid.getColumn(columnName).setRenderer(new CheckboxRenderer());
You can also easily add listener:
CheckboxRenderer renderer = new CheckboxRenderer();
grid.getColumn(columnName).setRenderer(renderer);
grid.getColumn(columnName).setHeaderCaption("");
renderer.addClickListener(e -> System.out.println("Hello listener!"));
If you only need a read-only checkbox, this worked for me:
grid.getColumn("columnId").setRenderer(new HtmlRenderer(), new BooleanConverter());
HtmlRenderer is provided by the Vaadin framework, and the boolean converter looks like this:
public class BooleanConverter implements Converter<String, Boolean>
{
#Override
public Boolean convertToModel(String value, Class<? extends Boolean> targetType, Locale locale) throws ConversionException
{
return null;
}
#Override
public String convertToPresentation(Boolean value, Class<? extends String> targetType, Locale locale) throws ConversionException
{
return "<input type='checkbox' disabled='disabled'" + (value.booleanValue() ? " checked" : "") + " />";
}
#Override
public Class<Boolean> getModelType()
{
return Boolean.class;
}
#Override
public Class<String> getPresentationType()
{
return String.class;
}
}
This will give you a native browser checkbox, however, not a Vaadin CheckBox.
You have to add generated columns for your checkboxes
GeneratedPropertyContainer gpcontainer = new GeneratedPropertyContainer(container);
gpcontainer.addGeneratedProperty("columnName",
new PropertyValueGenerator<CheckBox>() {
#Override
public CheckBox getValue(Item item, Object itemId,
Object propertyId) {
// set checkBox listener etc. in here
return new CheckBox();
}
#Override
public Class<CheckBox> getType() {
return CheckBox.class;
}
});
Grid grid = new Grid(gpcontainer);
You can find more detailed example in here in section "GeneratedPropertyContainer"
https://vaadin.com/docs/-/part/framework/datamodel/datamodel-container.html#datamodel.container.gpc
EDIT:
Also set `ComponentRenderer' for your column
mainGrid.addColumn(COLUMN).setRenderer(new ComponentRenderer())

How to change Swagger-ui URL?

I have tried to change the swagger URL, right now i have "http://localhost:8080/context-root/rest/swagger-ui.html", i want it to be "http://localhost:8080/swagger". I tried using the DOCKET.Host("swagger"), but browser is spinning. And its not loading screen.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
Can any one help with that?
Have you tried Path Provider ?
#Configuration
#EnableSwagger2
#Profile({"!production"})
public class SwaggerConfiguration extends WebMvcConfigurerAdapter {
#Autowired
private ServletContext servletContext;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.host("localhost")
.pathProvider(new RelativePathProvider(servletContext) {
#Override
public String getApplicationBasePath() {
return "/swagger";
}
})
.protocols(new HashSet<String>(Arrays.asList(protocols)))
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

spring boot custom login page

I am trying to add a custom login page for my boot strap application. I was following this tutorial. I couldn't make work with my custom login page.
Here is my pom.xml:
...
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>
...
MvcConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
registry.addViewController("/login").setViewName("login");
}
}
FrontendApp.java:
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import ch.qos.logback.classic.Logger;
#SpringBootApplication
#Import(value = MvcConfig.class)
public class FrontendApp {
private static Logger logger = (Logger) LoggerFactory.getLogger(FrontendApp.class);
public static void main(String[] args) {
SpringApplication app = new SpringApplication(FrontendApp.class);
app.run(args);
}
}
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(this.customAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.antMatchers("/resources/**").permitAll()
.antMatchers("**").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login");
}
}
I opened all the url's so Ican just check whether I can see /login or not.
CustomAuthenticationProvider.java
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
public CustomAuthenticationProvider() {
logger.info("*** CustomAuthenticationProvider created");
}
#Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if(authentication.getName().equals("karan") && authentication.getCredentials().equals("saman")) {
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), grantedAuths);
} else {
return null;
}
}
}
When I try localhost:8080/login I will get the following error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers
However when I try localhost:8080/ it will successfully redirect to index.html as I specified in MvcConfig.java.
Here is my login.html code:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="utf-8" />
<title>k</title>
</head>
I paste my login.html in /src/main/resources/templates and /src/main/webapp/ and /src/main/webapp/templates it still didn't work!
OK, so it was a simple mistake in pom.xml.
<!--<resources>-->
<!--<resource>-->
<!--<directory>src/main/resources</directory>-->
<!--<includes>-->
<!--<include>*</include>-->
<!--</includes>-->
<!--<filtering>true</filtering>-->
<!--</resource>-->
<!--</resources>-->
After I commented out these (as you see) from the pom file it worked perfectly.At least the above codes might be useful to someone else.

How to add labels dynamically to nodes in Neo4j from neo4j-ogm or spring-data-neo4j?

When I create a node, I want to add multiple labels, known at run-time, to the node. Is it possible to this in neo4j-ogm or spring-data-neo4j?
This isn't supported in the current version but is on the roadmap.
Add some dependences
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
Create an Enitity with lombok accessors
#NodeEntity
#Data
public class Content{
#Id
#GeneratedValue
private Long id; //Internal Neo4j Identifier. DONT TOUCH
// Your Bns Logic identifier
private Long myId
#Properties
private Map<String, String> properties = new HashMap<>();
#Labels
private List<String> labels = new ArrayList<>();
}
A Repository for your Entity
public interface ContentRepository extends Neo4jRepository<Content, Long> {
}
A simple controller to add your labels and properties in the Node
#RestController
#RequestMapping( produces = MediaType.APPLICATION_JSON_VALUE)
public class ContentController {
#Autowired
ContentRepository contentRepository;
#ApiOperation(value = "Create a Node", notes = "create a node", response = String.class)
#ApiResponses({
#ApiResponse(code = 201, message = "Success", response = String.class)
})
#PostMapping("/api/content")
public ResponseEntity<MyDTO> createNode(#RequestBody MyDTO requestWrapper ) {
//Create Database Entity from DTO
Content content = new Content();
//Add Labels
content.getLabels().addAll(requestWrapper.getLabelList());
//Add properties
requestWrapper.getHmap().forEach((k,v)->content.getProperties().put(k,v));
try {
contentRepository.save(content);
requestWrapper.setId(content.getId());
} catch (Exception e){
//e.printStackTrace();
}
return new ResponseEntity< MyDTO >(requestWrapper, HttpStatus.CREATED);
}

Spring Security OAuth2 AuthorizationServer

I'm playing around with spring-security-oauth2. I try to build some microservices with an authentication backend.
I set up an simple spring boot project with the following dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
and one Configuration Class
#Configuration
public class SecurityConfiguration {
#Autowired
#Qualifier("clientDetailsServiceBean")
private ClientDetailsService clientDetailsService;
#Autowired
#Qualifier("userDetailsServiceBean")
private UserDetailsService userDetailsService;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
#Bean(name = "authenticationManagerBean")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().userDetailsService(userDetailsService).formLogin().and().httpBasic();
}
}
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore());
}
#Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore());
return store;
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("permitAll()");
security.allowFormAuthenticationForClients();
}
}
My Implementation of Client- and UserDetailsService are very simple and always returns an object
#Service("clientDetailsServiceBean")
public class ClientDetailsServiceBean implements ClientDetailsService {
private static final Logger LOGGER = LoggerFactory.getLogger(ClientDetailsServiceBean.class);
#Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
LOGGER.info("Load client {}", clientId);
BaseClientDetails details = new BaseClientDetails();
details.setClientId(clientId);
details.setAuthorizedGrantTypes(Arrays.asList("password", "refresh_token", "client_credentials"));
details.setScope(Arrays.asList("trust"));
details.setAutoApproveScopes(Arrays.asList("trust"));
details.setAuthorities(Arrays.asList(new SimpleGrantedAuthority("client_role2")));
details.setResourceIds(Arrays.asList("clients"));
details.setClientSecret("secret");
return details;
}
}
#Service("userDetailsServiceBean")
public class UserDetailsServiceBean implements UserDetailsService {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailsServiceBean.class);
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LOGGER.info("Load user {}", username);
return new User(username, "password", Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")) );
}
}
But, when i try to receive an accessToken via
curl http://localhost:8081/oauth/token -d grant_type=client_credentials -d client_id=web_client -d client_secret=secret
i receive an error "Full authentication is required to access this resource" and when i try
curl http://localhost:8081/oauth/token -d grant_type=client_credentials -d client_id=web_client -d client_secret=secret --user web_client:secret
i receive an error "Bad credentials". From my point of view both should work, but it seems like my configuration is missing.
There are other things with OAuth that unclear to me:
I try to build an spring-mvc application with spring-security and a custom login form. It's possible to handle token request and refresh cycles by spring security without redirect to the authentication app?
In case of event driven application, it's possible to ensure the token is valid? In case of failure, the user clicks on button and an event is written but the processing of this will be hours later. How can i process the event with the user credentials?
Your inner #Configuration classes need to be static. I'm surprised the app starts at all, and probably the whole of your SecurityConfiguration is actually not being used.
It's possible to handle token request and refresh cycles by spring security without redirect to the authentication app?
Naturally. Did you read about the password and refresh_token grants in the spec? But in a web UI you are strongly advised to use the auth code grant (with the redirects), so that the user only enters his credentials in a trusted place.
the user clicks on button and an event is written but the processing of this will be hours later. How can i process the event with the user credentials?
Refresh tokens might be the best approach. The event obviously needs to be secure since it will have to contain the refresh token.

Resources