Hello

21. JWT를 위한 security 설정

by 볼빵빵오춘기

User.java - object 만들기

  • model 패키지 생성 후 User.java 생성 및 코드 작성한다.
  • String roles ⇒ getRoles 하면 결과 USER, ADMIN 로 나올것이고, getRoleList하면 USER, ADMIN 가 ‘,’를 기준으로 짤려서 List에 들어감으로써 0번째 인덱스에는 USER, 1번째 인덱스에는 ADMIN이 들어갈 것이다.
  • roles이 하나만 있다면 getRoleList()를 만들 필요 없다.
  • 애초에 model패키지에 Role 이라는 model(=class)를 만들어서 아래 코드처럼 처리해도 된다.(대신 아래 코드처럼 만든다면 getRoleList()는 필요x)
    ⇒ 하지만 Role 만듦으로써 테이블 하나 더 추가하는 것이 불편하므로 이 강의에서는 메소드를 이용한다.
    private Role roles; // USER, ADMIN

 


@Entity // DB 만들라는 어노테이션
@Data // getter, setter를 만들어주는 어노테이션
@NoArgsConstructor // 아무것도 없는 생성자를 만들어주는 어노테이션
@Table(name = "JWT_USER")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String username;
    private String password;
    private String roles; // USER, ADMIN

    public List<String> getRoleList(){
        if(this.roles.length()>0){
            return Arrays.asList(this.roles.split(","));
        }
        return new ArrayList<>();
    }

}

 

SecurityConfig.java - configure(HttpSecurity http)오버라이드

  • config 패키지 생성 후 SecurityConfig.java 생성 및 코드 추가한다.
  • WebSecurityConfigurerAdapter extends 해준다.
  • configure(HttpSecurity http) 오버라이드 한다. 
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CorsFilter corsFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); 
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // session 사용x 의미. STATELESS 서버로 만들겠다는 의미
            .and()
            .formLogin().disable() // formLogin을 안쓰겠단 의미 why? jwt서버이기 때문에 id,pw form로그인을 안하기 때문에
            .httpBasic().disable() // 기존 방식과 조금 다름을 알 수 있다.
            .authorizeRequests() // 인증이 필요한 주소요청이 왔을 때 아래와 같이 권한 설정을 하겠다.
            .antMatchers("/api/v1/user/**") // 해당 주소가 들어오면 밑에 권한만 접근 가능하다.
            .access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
            .antMatchers("/api/v1/manager/**")
            .access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
            .antMatchers("/api/v1/admin/**")
            .access("hasRole('ROLE_ADMIN')")
            .anyRequest().permitAll(); // 다른 요청은 권한 없이 접근가능
    }


}

 

CorsConfig.java - corsFilter()

  • config 패키지 밑에 CorsConfig.java 생성 후 코드 작성한다.
  • 스프링 관리할 수 있도록 @Configuration 붙여준다.
  • corsFilter() 을 빈으로 등록한다. (@Bean 붙여줌)
  • config.setAllowCredentials(false) 면 js로 요청했을 때 응답이 오지않는다. (이렇게 해주기만 하면 의미 없음. SecurityConfig.java 에 Filter로 등록을 해줘야 함.)
@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); // source에 "/api/**" 에 들어온 주소는 config설정을 따라라 해준다.

        return new CorsFilter(source); // source 담은 CorsFilter를 return
    }
}

 

SecurityConfig.java - configure(HttpSecurity http) 코드 추가 및 어노테이션 붙여주기

  • 내서버는 addFilter(corsFilter) 코드에 넣어줌으로써 모든요청은 addFilter(corsFilter) 코드를 타게됨으로써 cors정책에서 벗어날 수 있다. 따라서CrossOrigin 요청이 와도 다 허용이 된다.
  • cf) RestApiController.java 에 @CrossOrigin을 붙일 수 도 있지만 아래 코드와 적을 경우 인증이 필요한 요청은 다 거부된다.
    ⇒ 인증이 필요하지않은 요청만 허용이되고 인증이 필요한 요청 로그인을 해야지만 할 수 있는 요청은 아래와 같이 코드를 적는다고 해서 해결이 안된다.
  • ⇒ @CrossOrigin vs .addFilter(corsFilter)
  • 인증이 없을 때 @CrossOrigin 사용가능하지만 인증이 있을 때는 시큐리티 필터에 등록을 해야만 한다.
@CrossOrigin
@RestController
public class RestApiController {

@Configuration // IoC 할 수 있도록
@EnableWebSecurity // Security 활성화
@RequiredArgsConstructor 
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CorsFilter corsFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilter(corsFilter) // @CrossOrigin(인증x), 시큐리티 필터에 등록(인증o)
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .formLogin().disable()
                .httpBasic().disable()
                .authorizeRequests()
                .antMatchers("/api/v1/user/**")
                .access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
                .antMatchers("/api/v1/manager/**")
                .access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
                .antMatchers("/api/v1/admin/**")
                .access("hasRole('ROLE_ADMIN')")
                .anyRequest().permitAll();
    }

}

 

결과확인

  • http://localhost:8080/home 요청을 해보면 요청거부가 안되는 것을 확인됐다.
    Security를 쓰고는 있는데 Session을 사용하지않으니 모든 페이지로 접근이 가능한 것이다.
  • http://localhost:8080/api/v1/user/** , http://localhost:8080/api/v1/manager/** , http://localhost:8080/api/v1/admin/** 을 요청해보면 권한이 없어 403이뜬다.
  • 위의 권한 페이지 말고 다른 페이지를 들어가면 현재는 404 하지만 요청거부가 되지않는다.

 

Security 강의와 다른 점 

  • .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    ⇒ STATELESS 를 사용한다는 점 ⇒ 내 서버는 STATELESS 서버야!
  • .addFilter(corsFilter)
    ⇒ 내서버는 corsOrigin 정책을 안 쓸꺼야! 모든 요청을 허용할꺼야!
  • .formLogin().disable()
    ⇒ 내 서버는 formLogin을 안 쓸꺼야!

⇒ JWT서버 세팅할 시에는 전 프로젝트의 Security와 다른부분을 세팅해줘야한다.

'강의 따라하기 > JWT' 카테고리의 다른 글

23. JWT Filter 등록 테스트  (0) 2024.08.25
22. JWT Bearer 인증 방식  (0) 2024.08.25
20. JWT위한 yml파일 세팅  (0) 2024.08.25
19. JWT 프로젝트 세팅  (0) 2024.08.25
18. JWT 구조이해  (0) 2024.08.24

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기