public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {}
// ===> AbstractSecurityWebApplicationInitializer를 상속받으면 DelegatingFilterProxy가 자동 등록 됨.
간단한 보안 설정
@Configuration
@EnableWebSecurity // 웹 보안 활성
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
// WebSecurityConfigurerAdapter는 스프링 시큐리티 웹 보안 설정의 기본이라고 할 수 있음
=> WebSecurityConfigurer를 직접 구현하거나, WebSecurityConfigurerAdapter를 확장한 빈으로 설정해야함
@Configuration
@EnableWebMvcSecurity // 스프링MVC에 관련한 보안 활성
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
=> 스프링MVC 보안 활성, 스프링 MVC의 argument resolver를 설정하여, @AuthenticationPrincipal의 주체를 받을 수 있음,,, 폼바인딩 태그 라이브러리 사용하는 빈도 설정
WebSecurityConfigurerAdapter의 메소드
configure(AuthenticationManagerBuilder) : 사용자 세부서비스 + AuthenticationProvider 설정
configure(WebSecurity) : 필터 연결을 설정, 전역 보안에 영향을 주는 구성 설정
configure(HttpSecurity) : 인터셉터가 요청하는 URL 경로를 보호해야하는지에 대한 정의, 자신만의 인증 매커니즘 정의
시큐리티 상세 설정
인메모리 사용자 저장소 작업
* WebSecurityConfigurerAdapter에서 가장 쉬운 설정 방법은 configure(AuthenticationManagerBuilder) 오버라이딩
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication() // 인메모리 저장소 활성화
.withUser("user").password("pwd").roles("USER").and()
//.with ~~~ .pas~~ .auhorities("ROLE_USER") 와 상동
.withUser("admin").password("pwd").roles("USER", "ADMIN");
//.with ~~~ .pas~~ .auhorities("ROLE_USER", "ROLE_ADMIN") 와 상동
}
// 인메모리 저장소를 활용하여, user, admin에 각각 권한을 주는 함수
authorities()의 축약형 -> roles()
데이터베이스 테이블로 인증
기본사용자 쿼리 오버라이딩
* JDBC 지원 사용자 저장소에 인증하기위한 메소드 - jdbcAuthentcation()을 사용한다
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSoruce(dataSoucre)
.userBuySernameQuery(
"select username, password, true" +
"from People where username=?")
.authoritiesByUsernameQuery(
"select username, 'ROLE_USER' from People where username=?");
}
// 오토와이어링 된, dataSource를 인증의 수단으로 사용 => 자동연결
인증과 기본 권한에 대한 쿼리를 오버라이딩한, jdbcAuthentication()... (정확히 모르겠음..)
부호화된 암호
* 사용자 암호는 암호화된 데이터로 저장 -> 일반텍스트로는 인증을 할 수 없음 -> 이를위해 passwordEncoder()로 암호 복호화가 필요
* ldapAuthentication() 메소드 사용 : jdbcAuthentication()의 LDAP버전
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userSearchBase("ou=people") // 사용자를 찾는 기본 쿼리
.userSearchFilter("(uid={0})") // 사용자를 찾는 기본 LDAP 쿼리 필터
.groupSearchBase("ou=groups") // 그룹 찾는 기본 쿼리
.groupSearchFilter("members={0}"); // 그룹 찾는 쿼리 필터
}
* 애플리케이션에서, 모든 요청에 대한 보안관리가 있지는 않다(로그인 페이지), 몇몇 요청은 특정 권한만 가능하다(어드민 메뉴 등). 이러한 각각의 요청에 대해, 따로 보안이 필요한 경우를, 스프링 시큐리티는 대비할 수 있다.
configure(HttpSecurity) : 웹 요청(URL path)에 관한 설정용 메소드
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequest()
.antMatchers("/consumer/**").authenticated() // consumer/밑으로는 모두 인증
.antMatchers(HttpMethod.POST, "/search").hasRole("CONSUMER") // /search에서 POST, Consumer 롤을 가진사람만 가능
.anyRequest().permitAll(); // 위의 두 경우를 제외하곤, 모두 허용
=> antMatcher : Ant 스타일 동작이기 때문에, **사용 ( regexMatcher는 .* 사용)
스프링 표현식 보안
위의, access() 메소드를 통해, SpEL을 사용하여 더 높은 수준의 보안을 구현할 수 있다.
.antMatchers("/consumer/me").access("hasRole('ROLE_CONSUMER') and hasIpAddres('192.168.1.2')")
// ROLE과 IP주소에 관한 access 메소드
채널 보안 적용
등록폼에, HTTPS를 적용할 수 있다 --- HTTPS - 데이터를 주고 받는 과정에 '보안'요소가 추가, 서버간 통신 데이터가 전부 암호화