Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- stream
- C 언어 코딩 도장
- buffer
- Stack
- ㅅ
- datastructure
- Selection Sorting
- insertion sort
- R
- coding test
- s
- 이스케이프 문자
- Graph
- C programming
- 메모리구조
- 혼자 공부하는 C언어
- list 컬렉션
- JSON
- Serialization
- 이것이 자바다
- Algorithm
- 윤성우 열혈자료구조
- 알기쉬운 알고리즘
- 윤성우의 열혈 자료구조
Archives
- Today
- Total
Engineering Note
[Spring] Spring Security 적용하고 테스트 하기 본문
Spring Boot 프로젝트를 만들고 Security를 적용하고 테스트 한 과정입니다.
1. gralde Security 의존성
implementation 'org.springframework.boot:spring-boot-starter-security'
2. Member Entity
package com.shop.rest.commerce.entity;
import com.shop.rest.commerce.constant.Role;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Entity
@Table(name="member")
@Getter @Setter
@ToString
public class Member extends BaseEntity {
@Id
@Column(name="member_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(unique = true)
private String email;
private String password;
private String address;
@Enumerated(EnumType.STRING)
private Role role;
}
3. Member Repository
package com.shop.rest.commerce.repository;
import com.shop.rest.commerce.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository<Member, Long> {
Member findByEmail(String email);
}
4. Security Config
package com.shop.rest.commerce.config;
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.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // REST API는 CSRF 비활성화
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT 사용 시 세션 사용 안함
)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**", "/api/auth/**").permitAll() // 인증 없이 접근 가능
.requestMatchers("/api/admin/**").hasRole("ADMIN") // ADMIN만 접근 가능
.anyRequest().authenticated() // 나머지는 인증 필요
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4. TestController
- Security 적용을 테스트하기 위한 테스트용 컨트롤러
package com.shop.rest.commerce.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class TestController {
// 인증 없이 접근 가능
@GetMapping("/public/hello")
public Map<String, String> publicHello() {
return Map.of(
"message", "Public API - 인증 없이 접근 가능",
"status", "success"
);
}
// 인증 필요
@GetMapping("/user/hello")
public Map<String, String> userHello() {
return Map.of(
"message", "User API - 인증 필요",
"status", "success"
);
}
// ADMIN 권한 필요
@GetMapping("/admin/hello")
public Map<String, String> adminHello() {
return Map.of(
"message", "Admin API - ADMIN 권한 필요",
"status", "success"
);
}
// 인증 필요 (모든 역할)
@GetMapping("/protected/hello")
public Map<String, String> protectedHello() {
return Map.of(
"message", "Protected API - 인증된 사용자만 접근 가능",
"status", "success"
);
}
}
5. AuthContoller
- 회원가입용 컨트롤러
package com.shop.rest.commerce.controller;
import com.shop.rest.commerce.entity.Member;
import com.shop.rest.commerce.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final MemberService memberService;
private final PasswordEncoder passwordEncoder;
@PostMapping("/register")
public Map<String, String> register(@RequestBody Member member) {
// 비밀번호 암호화
member.setPassword(passwordEncoder.encode(member.getPassword()));
Member savedMember = memberService.saveMember(member);
return Map.of(
"message", "회원가입 성공",
"email", savedMember.getEmail()
);
}
}
6. Security 테스트
# 1. Public API (인증 없이 접근 가능) ✅
curl http://localhost:8080/api/public/hello
# 2. User API (인증 필요) ❌ 401 Unauthorized
curl http://localhost:8080/api/user/hello
# 3. Admin API (ADMIN 권한 필요) ❌ 401 Unauthorized
curl http://localhost:8080/api/admin/hello
# 4. Protected API (인증 필요) ❌ 401 Unauthorized
curl http://localhost:8080/api/protected/hello
# 5. 회원가입 (인증 없이 가능) ✅
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "test@test.com",
"password": "1234",
"name": "테스트",
"role": "USER"
}'
예상 결과:
| 엔드포인트 | 인증 | 예상 결과 |
| /api/public/hello | ✅ | 200 OK + JSON |
| /api/user/hello | ❌ | 401 Unauthorized |
| /api/admin/hello | ❌ | 401 Unauthorized |
| /api/protected/hello | ❌ | 401 Unauthorized |
| /api/auth/register | ✅ | 200 OK + 회원가입 성공 |
'Server' 카테고리의 다른 글
| [Server] Access Token과 Refresh Token을 사용하는 이유 (0) | 2025.12.19 |
|---|---|
| [JPA] em.flush(); (0) | 2025.12.15 |
| [Server] Pageable과 Page<E> 타입 (0) | 2025.10.15 |
| [Server] QueryDSL, Spring Boot 핵심 라이브러리 정리 (0) | 2025.10.07 |
| [Spring] BindingResult (0) | 2025.09.22 |
Comments