package com.codesign.base.security.filter;
import com.codesign.base.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecurityAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// TODO 나중에 유저정보를 request에서 username, password를 꺼내서 사용해야함
// String username = request.getParameter("username");
// String password = request.getParameter("password");
String testUsername = "test";
UserDetails authenticatedUser = customUserDetailsService.loadUserByUsername(testUsername);
// `authenticatedUser`와 `request`에 담긴 username과 password를 비교하는 로직이 있어야 될듯 싶다. 우선은 무조건 패스!
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(authenticatedUser.getUsername(), null, null);
SecurityContextHolder.getContext().setAuthentication(authToken);
filterChain.doFilter(request, response);
}
}
속성 | 설명 |
---|---|
OncePerRequestFilter | TODO |
doFilterInternal | OncePerRequestFilter 상속받은 메서드 |
customUserDetailsService.loadUserByUsername(username); | username만으로 조회된 사용자를 조회한다. 조회된 사용자 정보와 request 에 담긴 정보로 패스워드를 비교하여, 사용자 인증을 진행해야 할것같다. |
new UsernamePasswordAuthenticationToken() | 생성자 호출시, 들어가는 인자의 수에 따라 인증 여부가 다르다. 2개은 인증 실패, 3개는 인증 성공 authorities를 인자로 포함하는 두번째 생성자는 super.setAuthenticated(true); 로 인증시켜준다. |
setAuthentication() | TODO |
new UsernamePasswordAuthenticationToken()
생성자에 따른 this.setAuthenticated()
;
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 520L;
private final Object principal;
private Object credentials;
//첫번째 생성자
public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super((Collection)null);
this.principal = principal;
this.credentials = credentials;
this.setAuthenticated(false);
}
//두번쨰 생성자
public UsernamePasswordAuthenticationToken(Object principal,
Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
securityAuthenticationFilter
@Bean 등록 @Bean
public SecurityAuthenticationFilter securityAuthenticationFilter(){
return new SecurityAuthenticationFilter();
}
http.addFilterBefore()
추가
@Override
protected void configure(HttpSecurity http) throws Exception {
... 위와 동일
http.addFilterBefore(securityAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
속성 | 설명 |
---|---|
addFilterBefore() | TODO |
UsernamePasswordAuthenticationFilter.class | TODO |
UsernamePasswordAuthenticationFilter.class
필터를 거치기 전에 securityAuthenticationFilter()에서 인증한다.
SecurityConfig.java
전체
package com.codesign.base.configure;
import com.codesign.base.security.filter.SecurityAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public SecurityAuthenticationFilter securityAuthenticationFilter(){
return new SecurityAuthenticationFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/api/v1/test/permit-all").permitAll()
.antMatchers("/api/v1/test/auth").authenticated()
// .antMatchers("/**").authenticated()
// .anyRequest().permitAll().and()
.anyRequest().authenticated().and()
.formLogin().disable()
;
http.addFilterBefore(securityAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}