은은하게 코드 뿌시기

스프링 시큐리티 - WebSecurityConfigurerAdapter / HttpSecurity /AuthenticationManagerBuilder 본문

웹/Spring Boot

스프링 시큐리티 - WebSecurityConfigurerAdapter / HttpSecurity /AuthenticationManagerBuilder

은은하게미친자 2023. 4. 19. 17:10
728x90

1) WebSecurityConfigurerAdapter  클래스 

 : Spring Security에서 제공하는 클래스 중 하나로, 웹 보안 설정을 구성하는 데 사용됩니다.
이 클래스를 상속받아서 구현한 자바 설정 클래스에서는 configure() 메서드를 오버라이드하여 웹 보안 설정을 구현할 수 있습니다. configure() 메서드는 다양한  인스턴스를 매개변수로 받아서 해당 객체를 사용하여 보안 설정을 구성합니다.

 

1-1) configure 메서드에 매개변수로 주어 설정할수있는 객체 종류 와 그에 따른 다양한 사용 방법의 예

매개변수명  설명
HttpSecurity HTTP 보안 구성을 설정
 authorizeRequests(), formLogin(), httpBasic() 등의 메서드를 이용하여 HTTP 보안 구성을 설정할 수 있습니다.
1) 권한설정
antMatchers() 메서드를 사용하여 특정 URL에 대한 접근 권한을 설정하거나, hasRole() 메서드를 사용하여 특정 권한을 가진 사용자만 접근할 수 있도록 설정할 수 있습니다.
2) 보안설정
HTTPS, CSRF, X-Frame-Options 등 보안 관련 설정을 구현할 수 있습니다. 
3) 로그인설정
formLogin() 메서드를 사용하여 로그인 페이지를 설정하거나, defaultSuccessURL() 메서드를 사용하여 
로그인 성공 후 이동할 URL을 설정할 수 있습니다.
4) 로그아웃 설정
로그아웃 URL, 세션 무효화, 쿠키 삭제 등에 대한 설정을 구현할 수 있습니다. 
logout() 메서드를 사용하여 로그아웃 URL과 로그아웃 후 처리할 작업을 설정할 수 있습니다.
5) Remember Me 기능을 사용할 때의 설정
rememberMe() 메서드를 사용하여 인증처리에 필요한 필터를 자동으로 등록 하고, 이 필터가 사용자가 로그인 성공후 브라우저의 쿠키의 인증정보를 저장하도록합니다.
rememberMe() 메서드를 사용하여 Remember Me 기능을 설정할 수 있습니다.
WebSecurity 적 자원(이미지, 스크립트, 스타일시트) 에 대한 보안 구성을 설정합니다
ignoring() 메서드를 이용하여 보안 필터링에서 무시할 URL 패턴을 설정할 수 있습니다.
AuthenticationManagerBuilder 사용자 인증 방식을 설정
inMemoryAuthentication() 메서드를 이용하여 인메모리 기반의 사용자 인증을 설정하거나, userDetailsService() 메서드를 이용하여 DB 기반의 사용자 인증을 설정할 수 있습니다.
ResourceServerSecurityConfigurer OAuth2 보안 구성을 설정
tokenServices() 메서드를 이용하여 OAuth2 토큰 서비스를 설정하거나, resourceId() 메서드를 이용하여 OAuth2 리소스 ID를 설정할 수 있습니다.
OAuth2ClientConfigurer OAuth2 클라이언트 구성을 설정
clientId(), clientSecret(), authorizedGrantTypes(), redirectUris(), scopes() 등의 메서드를 이용하여 OAuth2 클라이언트 구성을 설정할 수 있습니다.
Jee JEE 보안 구성을 설정
rolePrefix(), authType() 등의 메서드를 이용하여 JEE 보안 구성을 설정할 수 있습니다.

 

 

1-2) HttpSecurity API

메소드 이름  인증/인가 설명
authorizeRequests() 인가 사용자 인증과 권한을 설정

antMatchers("url 패턴") 인가 URL 패턴에 따라 접근 권한을 설정 
hasRole("권한") 인가 특정권한을 가진 사용자만 접근허용
access() 인가 SpEL(스프링 표현 언어)을 사용하여, 특정 권한을 가진 사용자만 접근 허용
세부설정 가능
permitALL()  인가 모든 사용자에게 접근허용
formLogin() 인증 폼 태그 기반의 로그인 페이지 설정
loginPage("/login") 인증 로그인 페이지를 지정하는데 사용
좌측처럼 매개변수를 줄 경우 /login 화면으로 이동
사용자가 직접 작성한 로그인 화면을 설정시에도 사
defaultSuccessUrl("/home") 로그인 성공했을 때 이동한 URL을 지정하는데 사용
logout() 인증 로그아웃 설정
logoutUrl("/my/logout") 인증 로그아웃을 처리하는 페이지 설정
csrf() 인가 CSRF(Cross-Site Request Forgery) 설정
크로스사이트 위조 요청에 대한 설
.disable(); 인증 모든 보안구성을 비활성화
RESTfull을 사용하기위해서는 csrf기능을 비활성화해야함.
httpBasic() 인증 Http Basic 인증을 활성화합니다.
rememberMe() 인증 Remember Me 기능을 활성화합니다.
denyAll() 인가 모든 사용자가 해당 요청에 접근할 수 없도록 설정합니다.
fullyAuthenticated() 인가 완전히 인증된 사용자만 해당 요청에 접근할 수 있도록 설정합니다.
authenticated() 인가 인증된 모든 사용자가 해당 요청에 접근할 수 있도록 설정합니다.

1-2) AuthenticationManagerBuilder API

inMemoryAuthentication() 메모리에 사용자를 추가하여 인증하는 방법을 설정합니다.
withUser(String username) 사용자 이름을 추가합니다.
password(String password) 사용자 비밀번호를 추가합니다.
roles(String... roles) 사용자 역할을 추가합니다.
jdbcAuthentication() JDBC를 사용하여 사용자를 인증하는 방법을 설정합니다.
userDetailsService() 사용자 정보를 가져오는 UserDetailsService 인터페이스를 설정합니다.
authenticationProvider() 인증 처리를 담당하는 AuthenticationProvider 인터페이스를 설정합니다.
eraseCredentials() 인증 이후 자격 증명 정보를 삭제하도록 설정합니다.
userDnPatterns() LDAP에서 사용자 DN을 찾기 위한 패턴을 설정합니다.
ldapAuthentication() LDAP 서버를 사용하여 사용자를 인증하는 방법을 설정합니다.
addSecurityMethod() 보안 관련 메서드를 추가합니다.
apply() 다른 SecurityConfigurer를 현재 구성에 적용합니다.

AuthenticationManagerBuilder 사용예제

+ {noop} 은 비밀번호에 대한 암호화 처리를 하지 않겟다는 의미입니다.

실 사용에서는 일일히 하나씩 설정해주지않고

로그인 /로그아웃등 각각의 Handler 를 구현해서 각각 관리 하는 형태로 주로 사용 하는것 같다!

 

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
31
32
33
34
35
36
37
38
39
40
41
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    // 인메모리 방식으로 간단하게 인증 처리를 한다.
    auth.inMemoryAuthentication()
        .withUser("manager")
        .password("{noop}password")
        .roles("MANAGER");
    auth.inMemoryAuthentication()
        .withUser("admin")
        .password("{noop}password")
        .roles("ADMIN");
}
 
protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests() 
        // 모든 사용자가 접근 가능한 경로 
        .antMatchers("/""/home").permitAll() 
        // 인증된 사용자만 접근 가능한 경로
        .antMatchers("/member/**").authenticated() 
        // MANAGER 권한을 가진 사용자만 접근 가능한 경로
        .antMatchers("/manager/**").hasRole("MANAGER"
        // ADMIN 권한을 가진 사용자만 접근 가능한 경로
        .antMatchers("/admin/**").hasRole("ADMIN"
        .anyRequest().authenticated() 
        // 로그인 페이지 설정
        .and() 
        .formLogin() 
        .loginPage("/login"
        .defaultSuccessUrl("/loginSuccess"true)
        .permitAll() 
        .and() 
        // 로그아웃 페이지 설정
        .logout()
        .logoutSuccessUrl("/"+route+"/auth/logout")
        .invalidateHttpSession(true// 세션 강제 종료
        .permitAll()
        .and()
        // 접근권한 없음 페이지 설정
        .exceptionHandling().accessDeniedPage("/accessDenied"); 
}
 
cs

 

 

 

 

2-1) 클래스 사용 예제 

  • @EnableWebSecurity  : 이 클래스로부터 생성된 객체가 시큐리티 설정파일 임을 의미
  • WebSecurityConfigurerAdapter 의 configure() 메소드를 재정의해서 시큐리티의 설정을 커스터마이징할 수있다.
    • configure() 메소드는 HttpSecurity 객체를 매개변수로 받는데, 이 HttpSecurity 객체를 이용하여 애플리케이션 자언에 대한 인증과 인가를 제어 할 수있다.
    • WebSecurityConfigurerAdapter 클래스를 상속한 시큐리티 설정 클래스가 빈으로 등록되기만 해도(별도의 구현을 안하고 상속만 받은 클래스를 구현할 경우) 이제 더 이상 애플리케이션에서는 로그인을 강제하지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private CustomUserDetailsService customUserDetailsService;
 
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
 
    }
 
}
 
cs

 

 

 

2-2) 클래스 사용 예제 

configure(HttpSecurity http) 메서드에서는 HTTP 요청에 대한 보안 설정을 구현합니다. 

이 예제에서는 CSRF를 비활성화하고,

 "/api/auth/" 경로는 인증 없이 접근할 수 있도록 허용하고, 

"/api/" 경로는 인증된 사용자만 접근할 수 있도록 설정합니다. 

또한, Stateless한 세션을 사용하도록 설정하고,

 JwtAuthenticationFilter를 UsernamePasswordAuthenticationFilter 앞에 추가하여 JWT 인증을 처리하도록 합니다.

마지막으로, passwordEncoder() 메서드에서는 BCryptPasswordEncoder를 사용하여 비밀번호를 암호화하는 PasswordEncoder를 빈으로 등록합니다.

 

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
31
32
33
34
35
36
37
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private CustomUserDetailsService customUserDetailsService;
 
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
 
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/auth/**").permitAll()
            .antMatchers("/api/**").authenticated()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
 
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
 
 
    }
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
 
}
 
cs

 

 

728x90
Comments