Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ repositories {

dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

Expand Down
66 changes: 66 additions & 0 deletions src/main/java/org/javaspringcourse/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.javaspringcourse.config;

import org.javaspringcourse.domain.UserRole;
import org.springframework.context.annotation.Bean;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
private static final String[] PUBLIC_URLS = {
"/public/**"
};
private static final String[] ADMIN_URLS = {
"/admin/**"
};
private static final String[] SUPPORT_URLS = {
"/support/**"
};

@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
return http.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.logout(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(c -> c
.requestMatchers(PUBLIC_URLS)
.permitAll()
.requestMatchers(ADMIN_URLS)
.hasAuthority(UserRole.ROLE_ADMIN.name())
.requestMatchers(SUPPORT_URLS)
.hasAuthority(UserRole.ROLE_SUPPORT.name()))
.httpBasic(_ -> {})
.build();
}

@Bean
public PasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
var admin = User.builder()
.username("admin")
.password(passwordEncoder.encode("maozedong"))
.authorities(UserRole.ROLE_ADMIN)
.build();

var support = User.builder()
.username("support")
.password(passwordEncoder.encode("password"))
.authorities(UserRole.ROLE_SUPPORT)
.build();

return new InMemoryUserDetailsManager(admin, support);
}
}
31 changes: 31 additions & 0 deletions src/main/java/org/javaspringcourse/controller/ApiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.javaspringcourse.controller;

import org.javaspringcourse.dto.UserInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

@GetMapping("/public/api")
public String publicApi() {
return "Hello World";
}

@GetMapping("/admin/api")
public UserInfo getAdminInfo(@AuthenticationPrincipal UserDetails user) {
return new UserInfo(user.getUsername(), user.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.toList());
}

@GetMapping("/support/api")
public UserInfo getSupportUserInfo(@AuthenticationPrincipal UserDetails user) {
return new UserInfo(user.getUsername(), user.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.toList());
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/javaspringcourse/domain/UserRole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.javaspringcourse.domain;

import org.springframework.security.core.GrantedAuthority;

public enum UserRole implements GrantedAuthority {
ROLE_ADMIN,
ROLE_SUPPORT;

@Override
public String getAuthority() {
return this.name();
}
}
5 changes: 5 additions & 0 deletions src/main/java/org/javaspringcourse/dto/UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.javaspringcourse.dto;

import java.util.List;

public record UserInfo(String username, List<String> roles) {}