SpringBoot SpringSecurity 설정 1-3. 인증SecurityFilter 적용

jeonbang123·2023년 3월 31일
0

springboot

목록 보기
8/14

1. 인증 Filter 생성

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);
    }
}
속성
설명
OncePerRequestFilterTODO
doFilterInternalOncePerRequestFilter 상속받은 메서드
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);
    }

2. SecurityConfig에 인증 필터 적용

  • securityAuthenticationFilter @Bean 등록
    @Bean
    public SecurityAuthenticationFilter securityAuthenticationFilter(){
        return new SecurityAuthenticationFilter();
    }
  • config()에 http.addFilterBefore() 추가

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	... 위와 동일
    
		http.addFilterBefore(securityAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
속성
설명
addFilterBefore()TODO
UsernamePasswordAuthenticationFilter.classTODO

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);
    }
}

3. 테스트

  • /api/v1/test/auth 인증 성공 확인!

참조 https://sas-study.tistory.com/360

profile
Design Awesome Style Code

0개의 댓글