JWT

JWT를 사용하기 위한 security config 세팅

JANNNNNN 2024. 6. 30. 14:03

Maven

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.16.0</version>
</dependency>

application.yml

server:
  port: 8080
  servlet:
    context-path: /
    encoding:
      charset: UTF-8
      enabled: true
      force: true

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/{your_database}?serverTimezone=Asia/Seoul
    username: {your_username}
    password: {your_password}

  jpa:
    hibernate:
      ddl-auto: create #create update none
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true

User 생성

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String roles;

}

SecurityConfig

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CorsFilter corsFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // Session을 사용하지 않고, Stateless 서버를 만들겠다는 의미
                .and()
                .addFilter(corsFilter)  // Cross-Origin 정책 사용 X 모든 요청 허용 ** @CrossOrigin과의 차이점 : @CrossOrigin은 인증이 없을 때 문제, 그래서 직접 시큐리티 필터에 등록!
                    .formLogin().disable()
                    .httpBasic().disable()
                .authorizeRequests()
                    .antMatchers("/api/v1/user/**")
                        .hasAnyRole("USER", "MANAGER", "ADMIN")
                    .antMatchers("/api/v1/manager/**")
                        .hasAnyRole("MANAGER", "ADMIN")
                    .antMatchers("/api/v1/admin/**")
                        .hasRole("ADMIN")
                    .anyRequest().permitAll()
                ;
    }
}
  • csrf().disable() : 공격자가 사용자가 의도치 않은 요청(csrf)을 수행하게 하는 것을 disable한다.
  • sessionManagement().sessionCreationPolicy(SessionCreatationPolicy.STATLESS) : Session을 사용하지 않고, 서버를 Stateless하게 구성하겠다는 의미
  • formLogin(), httpBasic() : disable
  • "/api/v1/user/**" 로 들어오는 모든 요청은 USER, MANAGE, ADMIN 권한이 있어야 한다.
  • "/api/v1/manager/**" 로 들어오는 모든 요청은 MANAGE, ADMIN 권한이 있어야 한다.
  • "/api/v1/admin/**" 로 들어오는 모든 요청은 ADMIN 권한이 있어야 한다.
  • 그 외 나머지 요청은 모두 허용한다.

CorsConfig

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); //서버가 응답을 할 때 json을 자바스크립트에서 처리할 수 있게 할지 결정하는 것
        config.addAllowedOrigin("*"); //모든 ip에 응답을 허용하겠다
        config.addAllowedHeader("*"); //모든 header에 응답을 허용하겠다
        config.addAllowedMethod("*"); //모든 post, get, put, delete, patch 요청을 허용하겠다.
        source.registerCorsConfiguration("/api/**", config); // "/api/**" 경로에 대해 위의 설정 적용
        return new CorsFilter(source); // 설정된 source를 사용하여 CorsFilter 반환
    }
}

 

CORS (Cross-Origin Resource Sharing)는 웹 애플리케이션이 다른 도메인에서 리소스를 요청할 수 있도록 하는 메커니즘입니다. CORS Filter는 서버에 설치되어 CORS 정책을 적용하는 역할을 합니다. 서버는 클라이언트가 보내는 요청을 처리하기 전에 CORS 정책을 확인하고, 허용된 요청만을 처리합니다.