코드 그라데이션
JWT 예제 구현 (11) 버전 2.7.2 업데이트, 그래들 업데이트,RestResponseExceptionHandler 수정 본문
Spring/Security
JWT 예제 구현 (11) 버전 2.7.2 업데이트, 그래들 업데이트,RestResponseExceptionHandler 수정
완벽한 장면 2023. 12. 21. 22:43RestResponseEntityException
package inflearn.freejwt.handler;
import inflearn.freejwt.dto.ErrorDto;
import inflearn.freejwt.exception.DuplicateMemberException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import static org.springframework.http.HttpStatus.FORBIDDEN;
// @ControllerAdvice 어노테이션이 지정된 클래스는 전역 예외 처리를 위한 클래스임을 나타냅니다.
@ControllerAdvice
public class RestResponseEntityException extends ResponseEntityExceptionHandler {
// @ResponseStatus 어노테이션은 해당 메서드가 호출될 때 HTTP 응답 상태 코드를 CONFLICT(409)로 설정하도록 지정.
@ResponseStatus(HttpStatus.CONFLICT)
// @ExceptionHandler 어노테이션은 특정 예외 타입(DuplicateMemberException)을 처리하기 위한 메서드를 지정.
@ExceptionHandler(value = { DuplicateMemberException.class })
// @ResponseBody 어노테이션은 해당 메서드가 HTTP 응답 본문에 데이터를 직렬화하여 반환함.
@ResponseBody
// ResponseEntityExceptionHandler 클래스를 확장하여 예외를 처리하는 메서드.
// 이 메서드는 RuntimeException을 받고, 해당 예외와 WebRequest를 사용하여 ErrorDto를 생성하고 반환.
// 메서드명 변경
protected ErrorDto conflict(RuntimeException ex, WebRequest request) {
// ErrorDto 객체를 생성하고 HTTP 응답 상태 코드와 예외 메시지를 설정하여 반환.
return new ErrorDto(HttpStatus.CONFLICT.value(), ex.getMessage());
}
// 추가
protected ErrorDto forbidden(RuntimeException ex, WebRequest request) {
return new ErrorDto(FORBIDDEN.value(), ex.getMessage());
}
}
NotFoundMemberException
package inflearn.freejwt.exception;
// 사용자 정의 예외 클래스인 NotFoundMemberException을 정의.
public class NotFoundMemberException extends RuntimeException {
// 기본 생성자
public NotFoundMemberException() {
super();
}
// 메시지와 원인 예외를 받는 생성자
public NotFoundMemberException(String message, Throwable cause) {
super(message, cause);
}
// 메시지를 받는 생성자
public NotFoundMemberException(String message) {
super(message);
}
// 원인 예외를 받는 생성자
public NotFoundMemberException(Throwable cause) {
super(cause);
}
}
User의 테이블명 변경
@Entity
@Table(name = "'user'")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User { }
SecuricyConfig 수정
package inflearn.freejwt.config;
import inflearn.freejwt.jwt.JwtAccessDeniedHandler;
import inflearn.freejwt.jwt.JwtAuthenticationEntryPoint;
import inflearn.freejwt.jwt.JwtSecurityConfig;
import inflearn.freejwt.jwt.TokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
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;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;
@EnableWebSecurity // 기본적인 웹 시큐리티 설정을 활성화하겠다.
// 추가적 설정을 위해서 WebSecurityConfigurer 을 implement 하거나
// WebSecurityConfigureAdapter 를 extends 하는 방법이 있다.
@EnableGlobalMethodSecurity(prePostEnabled = true) // @PreAuthorize 어노테이션을 메서드 단위로 추가하기 위해서 사용
@RequiredArgsConstructor
public class SecurityConfig { // extend 삭제
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 빈으로 변경
/**
* h2-console 하위 모든 요청들과 파비콘 관련 요청은
* Spring Security 로직을 수행하지 않고 접근할 수 있게 configure 메서드를 오버라이드해서 내용을 추가해준다.
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/h2-console/**"
,"/favicon.ico"
,"/error");
}
/**
*
* @param http the {@link HttpSecurity} to modify
* @throws Exception
*
* 많은 부분들을 추가
* : 토큰을 사용하기 때문에 csrf 설정은 disable
* Exception을 핸들링할 때 만들었던 클래스들을 추가한다.
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// token을 사용하는 방식이기 때문에 csrf를 disable한다.
httpSecurity.csrf().disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.accessDeniedHandler(jwtAccessDeniedHandler)
// h2-console을 위한 설정
.and()
.headers()
.frameOptions()
.sameOrigin()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // session을 사용하지 않음.
.and()
.authorizeRequests() // HttpServletRequest를 사용하는 요청들에 대한 접근 제한을 설정하겠다.
.antMatchers("/api/hello").permitAll() // /api/hello 에 대한 요청은 인증 없이 접근을 허용하겠다.
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/signup").permitAll()
.anyRequest().authenticated() // 나머지 요청들에 대해서는 인증을 받아야 한다.
.and()
.apply(new JwtSecurityConfig(tokenProvider));
// 여기도 추가
return httpSecurity.build();
}
}
gradle-wrapper.properties
그래들 버전 업그레이드
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
}
group = 'inflearn'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
}
tasks.named('test') {
useJUnitPlatform()
}
728x90
'Spring > Security' 카테고리의 다른 글
[중간점검] 스프링 3버전 업그레이드 이후 전체 코드 점검(3.0.1) /3.05 (0) | 2023.12.26 |
---|---|
JWT 예제 구현 (12) 3.0.1 버전 업그레이드 (1) | 2023.12.23 |
[중간점검] 또 여기까지 전체 코드 정리 / 버전 2.5.3 (0) | 2023.12.20 |
JWT 예제 구현 (10) Response 시 DTO를 통해서만 응답하도록 변경 (0) | 2023.12.19 |
JWT 예제 구현 (9) Exception 세분화, 리다이렉트 수정, Response 로직 변경, 리다이렉트 테스트 추가 (1) | 2023.12.18 |
Comments