[Spring Security - 3] Config

배지원·2023년 6월 12일
0

SpringSecurity

목록 보기
3/3

1. 필터 Off

  • disable( ); 을 통해 특정 필터의 기능을 off시킬 수 있다.
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  http
      .httpBasic().disable(); // HTTP Basic 인증 비활성화
  }

2. 로그인 & 로그아웃 페이지 관련 기능

  • 로그인 페이지를 지정하고 로그인에 성공했을 경우 이동할 URL을 지정한다.
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  http
      .httpBasic().disable(); // HTTP Basic 인증 비활성화
        // login
        .formLogin()
                .loginPage("/login")	// 로그인 페이지 지정
                .defaultSuccessUrl("/")	// 로그인 성공시 이동할 페이지
                .permitAll(); // 모두 허용
  }
  • 로그아웃 URL을 지정하고 로그아웃을 했을 경우 이동할 URL을 지정한다.
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  http
      .httpBasic().disable(); // HTTP Basic 인증 비활성화
        // login
        .formLogin()
                .loginPage("/login")	// 로그인 페이지 지정
                .defaultSuccessUrl("/")	// 로그인 성공시 이동할 페이지
                .permitAll(); // 모두 허용
        // logout
        .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))	// 로그아웃 페이지 지정
                .logoutSuccessUrl("/");	// 로그아웃 성공시 이동할 페이지
  }

3. Url Machers 관련 기능

  • antMatchers() : URL 경로를 직접 지정

  • mvcMathcers("/test") : /test로 시작하는 url을 지정함

  • regexMathcers() : 정규표현식으로 매칭함

  • requestMatchers() : antMatchers, mvcMatchers, regexMatchers는 결국에 requestMatcher()로 이루어져 있다. 명확하게 요청 대상을 지정하는 경우에는 requestMatchers 사용

    http.authorizeRequests()
                   // /와 /home은 모두에게 허용
                   .antMatchers("/", "/home", "/signup").permitAll()
                   // hello 페이지는 USER 롤을 가진 유저에게만 허용
         .antMatchers("/admin").hasRole("ADMIN")	// admin 페이지는 ADMIN권한만 접근 가능
                   .mvcMatchers("/login").permitAll()	// /login 으로 시작하는 URL은 모두 접근 가능
    

4. 인가 관련 설정

  • authorizeRequests() : 인가를 설정

  • permitAll() : 모든 사람에게 허용함

  • hasRole() : 권한을 검증함

  • authenticated() : 인증이 된 사람만 접근 가능

  • anyRequest() : 이 외의 모든 요청

    http.authorizeRequests()		// 인가 설정
                   .antMatchers("/", "/home", "/signup").permitAll()  // /와 /home은 모두에게 허용
                   // hello 페이지는 USER 롤을 가진 유저에게만 허용
                   .antMatchers("/admin").hasRole("ADMIN")	// 권한이 ADMIN인 사람만 접근 가능
                   .anyRequest().authenticated();	// 위에서 정한 설정 외의 요청에는 인증이 된 사람만 접근 가능

5. lgnoring

  • SpringSecurity자체를 적용하고 싶지 않은 특정 리소스에 적용함

  • 특정 URL 패턴이나 자원을 보안 필터 체인에서 제외하도록 설정하는 기능입니다. 즉, 지정된 URL 패턴이나 자원에 대한 접근은 Spring Security에 의해 보호받지 않게 되어 인증 및 인가 과정을 건너뛸 수 있습니다.

  • 일반적으로 정적 자원(예: CSS, JavaScript, 이미지 파일 등)이나 공개적으로 접근 가능한 페이지에 대해 이런 설정을 사용합니다. 이를 통해 성능 최적화와 개발의 편의성을 도모할 수 있습니다.

       @Override
       public void configure(WebSecurity web) {
           // ignoring() : springsecurity의 보호를 받지 않을 파일 설정
           // 정적 리소스 spring security 대상에서 제외
           // web.ignoring().antMatchers("/images/**", "/css/**"); // 아래 코드와 같은 코드입니다.
           web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());    // Static폴더에 있는 파일들을 ignoring 시키겠다
       }

    ❓ 그렇다면 모든 유저에게 권한을 허용해주는 permitAll( )과 lgnoring의 역할은 같지 않을까라는 생각을 하게 되는데 결론은 역할은 같다이다 하지만, 속도적으로 봤을때는 lgnoring은 어떤 필터도 적용되지 않으므로 성능적으로 우세하다. 따라서, 필터를 적용시킬 필요가 없는 파일은 Ignoring을 사용하여 제외 시켜야 합니다.

Config 완성 코드

1. WebSecurityConfigurerAdapter 상속받아 사용하는법

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{

    private final UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // basic authentication
        http.httpBasic().disable(); // basic authentication filter 비활성화
        // csrf
        http.csrf();            // csrf 외부 접근 차단
        // remember-me
        http.rememberMe();      // 사용자 데이터 기억
        // anonymous
        http.anonymous().principal("방문자");      // 인증하지 않은 사용자 접근 허용(방문자 신분으로 header에 저장)
        // authorization
        http.authorizeRequests()        // 인가 설정
                .antMatchers("/", "/home", "/signup").permitAll()  // .antMatchers() : 경로 지정, permitAll() : 모든 인원에게 권한 허용
                .antMatchers("/note").hasRole("USER")
                .antMatchers("/admin").hasRole("ADMIN")     // admin 페이지는 ADMIN 롤을 가진 유저에게만 허용
                .antMatchers(HttpMethod.POST, "/notice").hasRole("ADMIN")
                .antMatchers(HttpMethod.DELETE, "/notice").hasRole("ADMIN")
                .anyRequest().authenticated();          // 위에서 설정한 페이지를 제외한 나머지에서는 인증이 된 사람만 접근 가능
                                                        // anyRequest() : 나머지 값, authenticated() : 인증이 된 사람만 접근 가능
        // login
        http.formLogin()        // 로그인 페이지 설정
                .loginPage("/login")        // 로그인 페이지 URL 주소 지정
                .defaultSuccessUrl("/")     // 로그인 성공시 이동할 URL 주소 지정
                .permitAll(); // 모든 사용자에게 허용
        // logout
        http.logout()           // 로그아웃 페이지 설정
//              .logoutUrl("/logout")   로그아웃은 따로 페이지가 필요없으므로 아래의 코드 사용
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))  // 로그아웃은 Post 형식으로 오기 때문에 따로 페이지가 없으므로 로그아웃 요청을 "/logout" URL로 지정
                .logoutSuccessUrl("/");      // 로그아웃 성공시 이동할 URL 주소 지정
    }

    @Override
    public void configure(WebSecurity web) {
        // ignoring() : springsecurity의 보호를 받지 않을 파일 설정
        // 정적 리소스 spring security 대상에서 제외
        // web.ignoring().antMatchers("/images/**", "/css/**"); // 아래 코드와 같은 코드입니다.
        web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());    // Static폴더에 있는 파일들을 ignoring 시키겠다
    }

    /**
     * UserDetailsService 구현
     *
     * @return UserDetailsService
     */
    // 아이디 비밀번호를 검사하기 위해서 User Entity에서 UserDetails를 implemnets를 받아 기존 양식을 Override해서 사용함
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return username -> {
            User user = userService.findByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException(username);
            }
            return user;
        };
    }
}

2. SecurityFilterChain 사용법

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SpringSecurityConfigFilterChain {
    // FilterChain
    private final UserService userService;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{
        return httpSecurity
                // basic authentication filter disable
                .httpBasic().disable()
                // 외부 요청 금지
                .csrf()
                .and()
                // 사용자 기억
                .rememberMe()
                .and()
                // 경로 권한 설정
                .authorizeRequests()
                    .antMatchers("/","/home","/signup").permitAll()
                    .antMatchers("/note").hasRole("USER")
                    .antMatchers("/admin").hasRole("ADMIN")
                    .antMatchers(HttpMethod.GET,"/notice").authenticated()      // notice GET url은 인증받은 사람 접근 가능
                    .antMatchers(HttpMethod.POST,"/notice").hasRole("ADMIN")    // notice POST url은 관리자만 접근 가능
                    .antMatchers().authenticated()
                .and()
                // 로그인 관련 필터 설정
                .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/")
                    .permitAll()
                .and()
                // 로그아웃 관련 피터 설정
                .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
                .and()
                .build();
    }

    // SpringSecurity Filter가 필요없는 파일 Ignoring 작업
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());    // 정적 파일 ignoring
    }


    @Bean
    public UserDetailsService userDetailsService() {
        return username ->{
            User user = userService.findByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException(username);
            }
            return user;
        };
    }
}
profile
Web Developer

0개의 댓글