๋ก๊ทธ์ธ
์ด์ ํ์ด์ง
์ด์ ํ์ด์ง ๋ด์ฉ์ ์ด์ด์ ์งํํฉ๋๋ค.
Code
Preview
1.
๋ฉ์ธ ํ๋ฉด
2.
๋ก๊ทธ์ธ ํ๋ฉด
์์ ํ๋ก์ธ์ค
1.
ํ๋ก์ ํธ ์์ฑ
2.
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
3.
์์ฒญ ๊ฒฝ๋ก ๋งคํ
Preview
1.
๋ฉ์ธ ํ๋ฉด
2.
๋ก๊ทธ์ธ ํ๋ฉด
3.
๋ฉ์ธ ํ๋ฉด (๋ก๊ทธ์ธ ์๋ฃ)
๋ฉ์ธ ํ๋ฉด
๋ก๊ทธ์ธ ํ๋ฉด
๋ฉ์ธ ํ๋ฉด (๋ก๊ทธ์ธ ์๋ฃ)
์์ ํ๋ก์ธ์ค
1.
ํ๋ก์ ํธ ์์ฑ
โข
โข
spring boot version : 3.x.x
โข
spring security version : 6.x.x
โข
์์กด์ฑ ์ค์
โฆ
Spring Web
โฆ
Spring Boot DevTools
โฆ
Spring Security
โฆ
Lombok
โฆ
Thymeleaf
โฆ
MySQL Driver
โฆ
Mybatis Framework
2.
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
โข
ํ๋ก์ ํธ ์์ฑ
build.gradle
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.5.9'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.aloha'
version = '0.0.1-SNAPSHOT'
description = 'Demo project for Spring Boot'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(23)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.5'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.5'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
Java
๋ณต์ฌ
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
~/config/SecurityConfig.java
UserDetailsService ๋น ๋ฑ๋ก
UserDetailsService ๋น์ ๋ฑ๋กํ์ฌ, ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์ค์ ํด์ฃผ์ด ์ธ์ฆ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ๋ค.
โข
โข
private final DataSource dataSource;
// @Autowired private DataSource dataSource;
@Bean
public UserDetailsService userDetailsService() {
JdbcUserDetailsManager userDetailsManager
= new JdbcUserDetailsManager(dataSource);
// ์ฌ์ฉ์ ์ธ์ฆ ์ฟผ๋ฆฌ
String sql1 = " SELECT username, password, enabled "
+ " FROM user "
+ " WHERE username = ? "
;
// ์ฌ์ฉ์ ๊ถํ ์ฟผ๋ฆฌ
String sql2 = " SELECT username, auth "
+ " FROM user_auth "
+ " WHERE username = ? "
;
userDetailsManager.setUsersByUsernameQuery(sql1);
userDetailsManager.setAuthoritiesByUsernameQuery(sql2);
return userDetailsManager;
}
Java
๋ณต์ฌ
AuthenticationManager ๋น ๋ฑ๋ก
/**
* ๐ AuthenticationManager ์ธ์ฆ ๊ด๋ฆฌ์ ๋น ๋ฑ๋ก
* @param authenticationConfiguration
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration ) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
Java
๋ณต์ฌ
SecurityConfig.java
@Slf4j
@Configuration
@EnableWebSecurity // ์คํ๋ง ์ํ๋ฆฌํฐ ์ค์ ๋น์ผ๋ก ๋ฑ๋ก
@RequiredArgsConstructor
public class SecurityConfig {
private final DataSource dataSource;
// @Autowired private DataSource dataSource;
/**
* ์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
* @param http
* @return
* @throws Exception
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
log.info("์คํ๋ง ์ํ๋ฆฌํฐ ์ค์ ");
// โ
์ธ๊ฐ ์ค์
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/**").permitAll() // ์ ์ฒด ํ์ฉ
);
// ๐ ํผ ๋ก๊ทธ์ธ ์ค์
http.formLogin(login -> login.permitAll());
return http.build();
}
/**
* ๐ ์ํธํ ๋ฐฉ์ ๋น ๋ฑ๋ก
* @return
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* ๐ JDBC ์ธ์ฆ ๋ฐฉ์ ์ฌ์ฉ์์ ๋ณด ์๋น์ค ๋น ๋ฑ๋ก
* @return
*/
@Bean
public UserDetailsService userDetailsService() {
JdbcUserDetailsManager userDetailsManager = new JdbcUserDetailsManager(dataSource);
// ์ฌ์ฉ์ ์ธ์ฆ ์ฟผ๋ฆฌ
String sql1 = " SELECT username, password, enabled "
+ " FROM user "
+ " WHERE username = ? "
;
// ์ฌ์ฉ์ ๊ถํ ์ฟผ๋ฆฌ
String sql2 = " SELECT username, auth "
+ " FROM user_auth "
+ " WHERE username = ? "
;
userDetailsManager.setUsersByUsernameQuery(sql1);
userDetailsManager.setAuthoritiesByUsernameQuery(sql2);
return userDetailsManager;
}
/**
* ๐ AuthenticationManager ์ธ์ฆ ๊ด๋ฆฌ์ ๋น ๋ฑ๋ก
* @param authenticationConfiguration
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration ) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
Java
๋ณต์ฌ
HomeController.java
@GetMapping("")
public String home(@AuthenticationPrincipal User authAuth, Model model) throws Exception {
log.info(":::::::::: ๋ฉ์ธ ํ๋ฉด ::::::::::");
String username = authAuth.getUsername(); // ์ธ์ฆ๋ ์ฌ์ฉ์ ์์ด๋
log.info("username : " + username);
Users user = userService.select(username); // ์์ด๋๋ก ํ์ ์ ๋ณด ์กฐํ
log.info("user : " + user);
model.addAttribute("user", user); // ๋ชจ๋ธ์ ์ฌ์ฉ์ ๊ฐ์ฒด ๋ฑ๋ก
return "index";
}
Java
๋ณต์ฌ
๋ฉ์ธ ํ๋ฉด์์ ์ธ์ฆ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์์ ์ถ๋ ฅํด๋ณด๊ฒ ์ต๋๋ค.
@AuthenticationPrincipal
ํ์ฌ ์ธ์ฆ๋ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์ฃผ์
๋ฐ์ต๋๋ค.
org.springframework.security.core.userdetails.User ๊ฐ์ฒด ์ ๋ณด๋ก ์ธ์ฆ๋ ์ฌ์ฉ์ ์ ๋ณด์ ๊ฐ์ ธ์จ๋ค.
๋ฉ์๋ | ์ค๋ช
|
getUsername() | ์ธ์ฆ๋ ์ฌ์ฉ์์ ์ฌ์ฉ์๋ช
(username) |
getPassword() | ์ธ์ฆ๋ ์ฌ์ฉ์์ ์ํธ (password)๋ฅผ ๋ฐํํฉ๋๋ค. |
getAuthorities() | ์ฌ์ฉ์์ ๊ถํ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. GrantedAuthority ๊ฐ์ฒด์ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํฉ๋๋ค. |
isEnabled() | ์ฌ์ฉ์๊ฐ ํ์ฑํ ๋์ด ์๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํํฉ๋๋ค. (ํ์ฑํ๋๋ฉด true, ๋นํ์ฑํ๋๋ฉด false) |
isAccountNonExpired() | ์ฌ์ฉ์์ ๊ณ์ ์ด ๋ง๋ฃ๋์ง ์์๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํํฉ๋๋ค. (๊ณ์ ์ด ๋ง๋ฃ๋์ง ์์ผ๋ฉด true) |
isCredentialsNonExpired() | ์ฌ์ฉ์์ ์๊ฒฉ ์ฆ๋ช
(๋น๋ฐ๋ฒํธ ๋ฑ)์ด ๋ง๋ฃ๋์ง ์์๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํํฉ๋๋ค. (๋น๋ฐ๋ฒํธ๊ฐ ๋ง๋ฃ๋์ง ์์ผ๋ฉด true) |
isAccountNonLocked() | ์ฌ์ฉ์์ ๊ณ์ ์ด ์ ๊ฒจ ์์ง ์์์ง ์ฌ๋ถ๋ฅผ ๋ฐํํฉ๋๋ค. (์ ๊ธฐ์ง ์์ผ๋ฉด true) |






