Add security and actuator

This commit is contained in:
Petros Stergioulas
2020-05-16 19:46:43 +02:00
parent bb7ac442b1
commit 94f88c4489
4 changed files with 180 additions and 5 deletions

View File

@@ -1,12 +1,12 @@
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'org.springframework.boot' version '2.3.0.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'io.reflectoring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'
sourceCompatibility = '1.8'
configurations {
compileOnly {
@@ -19,7 +19,9 @@ repositories {
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springdoc:springdoc-openapi-ui:1.3.3'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

View File

@@ -1,13 +1,178 @@
package io.reflectoring.codefirst;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.servers.Server;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@RequestMapping("/api/todos")
@Tag(name = "Todo API", description = "euismod in pellentesque massa placerat duis ultricies lacus sed turpis")
@SecurityRequirement(name = "api")
interface TodoApi {
@GetMapping
@ResponseStatus(code = HttpStatus.OK)
List<Todo> findAll();
@GetMapping("/{id}")
@ResponseStatus(code = HttpStatus.OK)
Todo findById(@PathVariable String id);
@PostMapping
@ResponseStatus(code = HttpStatus.CREATED)
Todo save(@RequestBody Todo todo);
@PutMapping("/{id}")
@ResponseStatus(code = HttpStatus.OK)
Todo update(@PathVariable String id, @RequestBody Todo todo);
@DeleteMapping("/{id}")
@ResponseStatus(code = HttpStatus.NO_CONTENT)
void delete(@PathVariable String id);
}
@RequestMapping("/unsecured")
@Tag(name = "Unsecured API", description = "aliquet nec ullamcorper sit amet risus nullam eget felis eget")
interface UnsecuredApi {
@GetMapping
@ResponseStatus(code = HttpStatus.OK)
String unsecured();
}
@SpringBootApplication
public class CodeFirstApplication {
public static void main(String[] args) {
SpringApplication.run(CodeFirstApplication.class, args);
}
}
@OpenAPIDefinition(
info = @Info(
title = "Code-First Approach (reflectoring.io)",
description = "" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur et rhoncus quam. Aenean quis augue ac eros pulvinar malesuada. " +
"In sagittis elit egestas tincidunt iaculis. " +
"Donec eu lacus vitae nulla varius consectetur a vel quam. Aliquam erat volutpat. Duis eget ullamcorper tellus",
contact = @Contact(name = "Reflectoring", url = "https://reflectoring.io", email = "petros.stergioulas94@gmail.com"),
license = @License(name = "MIT Licence", url = "https://github.com/thombergs/code-examples/blob/master/LICENSE")),
servers = @Server(url = "http://localhost:8080")
)
@SecurityScheme(scheme = "basic", type = SecuritySchemeType.HTTP, name = "api", in = SecuritySchemeIn.HEADER)
class OpenAPIConfiguration {
}
@EnableWebSecurity
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/unsecured", "/swagger-ui/**", "/reflectoring-openapi/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("password"))
.authorities("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@NoArgsConstructor
@AllArgsConstructor
@Data
class Todo {
private String id;
private String text;
}
@RestController
class TodoController implements TodoApi {
private List<Todo> todos;
@Override
public List<Todo> findAll() {
return todos;
}
@Override
public Todo findById(String id) {
return todos.stream().filter(todo -> todo.getId().equals(id)).findFirst().orElseGet(null);
}
@Override
public Todo save(Todo todo) {
todos.add(todo);
return todo;
}
@Override
public Todo update(String id, Todo todo) {
for (Todo t : todos) {
if (t.getId().equals(id)) {
t.setText(todo.getText());
}
}
return todo;
}
@Override
public void delete(String id) {
todos.removeIf(t -> t.getId().equals(id));
}
@PostConstruct
public void onInit() {
todos = Stream.of("Groceries", "Lisa's birthday")
.map(todo -> new Todo(UUID.randomUUID().toString(), todo))
.collect(Collectors.toList());
}
}
@RestController
class Unsecured implements UnsecuredApi {
@Override
public String unsecured() {
return "unsecured";
}
}

View File

@@ -0,0 +1,9 @@
springdoc:
api-docs:
path: /reflectoring-openapi
show-actuator: true
management:
endpoints:
web:
exposure:
include: "*"