Hyunseok
프로그래밍/개인홈페이지 :: Spring boot + JWT + OAuth2 + Redis로 Restful 로그인을 만들어보자 完
2022. 11. 28. 14:29

2022.11.28 - [프로그래밍/ㄴ 개인홈페이지] - :: Spring boot + JWT + OAuth2 + Redis로 Restful 로그인을 만들어보자 3

 

3편에서 계속되는 내용입니다

 

이번편은 securityconfig을 설정해보자

 

1. Securityconfig

@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
    private final BlogOauthService boser;
    private final MembersRepository mrepo;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager)
            throws Exception {
        http.csrf().disable();
        http.httpBasic().disable();
        http.formLogin().disable();
        http.logout().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(blogFilterForLogin(authenticationManager),UsernamePasswordAuthenticationFilter.class);
        http.oauth2Login()
        	.authorizationEndpoint()
            .baseUri("/oauth2")
        .and()
        	.userInfoEndpoint()
            .userService(boser)
        .and()
        	.successHandler(blogOauthSuccessHandler());
        return http.build();
    }

    @Bean
    public BlogFilterForLogin blogFilterForLogin(AuthenticationManager authenticationManager) {
        BlogFilterForLogin restLogin = new BlogFilterForLogin(jwtManager());
        restLogin.setAuthenticationManager(authenticationManager);
        return restLogin;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public BlogOauthSuccessHandler blogOauthSuccessHandler(){
        return new BlogOauthSuccessHandler(jwtManager(), mrepo);
    }

    @Bean
    public JwtManager jwtManager() {
        return new JwtManager();
    }

}

일단 httpbasic, formlogin, logout, session을 싸악 안 쓰니 다 해제해주고.. 

간단하게 login과 /oauth2에만 필터를 걸어준다

oauth2를 저렇게 적어두고

나중에 프론트에서 백엔드로 http://localhost:백엔드포트/oauth2/google 접속하면 

시큐리티가 알아서 google oauth2 인증으로 처리한다(매우편하다)

 

 

 

순서를 생각해보면

 

일단 스프링이 login/oauth의 주소로 들어오는 신호를 먼저 가져온다

 

1.  /login일 경우

클라이언트에서 값을 보냅니다> 

http request가 security로 들어갑니다>

filter+antmatcher로 login이 맞는지 확인합니다>

attemptauthentication에서 받은 request으로 유저 토큰으로 userdetailsservice로 보냅니다>

userdetailsservice에서 유저를 검사합니다 없으면 throw, 있으면 만들어둔 로그인용 도메인으로 유저 정보를 만들어 넘깁니다>

통과하면 성공한 것이니 successfulAuthentication로 넘깁니다 여기에서 클라이언트로 쏴줄 정보를 만듭니다>

클라이언트는 지정한 content-type+내용으로 값을 반환받습니다 

 

2. /oauth 일 경우

클라이언트에서 미리 설정해둔 baseurl인  /oauth2로 접근합니다>

스프링은 그 신호를 받고 oauth2loginauthenticationfilter로 신호를 보냅니다>

그리고 로그인 페이지를 호출하여 해당 리소스 서버에 정보를 받아옵니다(구글 로그인) >

받아온 리소스를 기본 oauth2의 attempt authentication으로 보내서 토큰을 만들고 인증과정을 시작합니다>

여기서 oauth2의 userservice를 불러와서 유저 정보를 만듭니다>

만드는 것에 성공하였으면 이 역시 successfulauthentication으로 넘깁니다

 

 

여기서 1번 과정은 여타 다른 시큐리티 예제와 같고..

나는 2번 과정에서 맨 마지막 과정에서 seveletresponse, 그러니까 클라이언트로 쏴줄 내용에

그냥 냅다 액세스토큰과 리프래시토큰을 만들어서 클라이언트로 쏴줬다

그러면 다른 복잡한 절차 없이 자동으로 프론트가 쿠키를 가지고 사용할 수 있게끔 된다..

 

다른 글보다 글자 수가 많지만.. 이러한 루트로 돌아간다는 걸 항상 생각하자

 

이제 프론트에서.. 나 같은 경우는 vue를 사용했는데 

 

vue에서 백엔드주소/login으로 시큐리티에 필요한 정보를 fetch한다 

그럼 백엔드가 글의 과정을 수행하고 successfulauthentication의 과정에서 fetch의 결과로 내용을 쏴주게 된다

 

글이 좀 길어서 힘들 수도 있지만... 정리하면서 다시금 몇 가지 깨달은 점도 있고..

 

다른 oauth2 + jwt글을 보니 아예 oauth2 과정 자체를 뜯어서 다시 만든 분도 몇 분 보이고..

 

한번 하니 그리 어려운 내용이 아니라 매우 만족스러운 내용이다

 

다음에는 여러 인증체계를 가진 security도 만들어 적용시켜봐야겠다

 

 

모든 코드는.. 아래에서 확인할 수 있다

 

https://github.com/B-HS/BBlog

 

GitHub - B-HS/BBlog: 프론트/백엔드 종합 블로그 프로젝트

프론트/백엔드 종합 블로그 프로젝트. Contribute to B-HS/BBlog development by creating an account on GitHub.

github.com

 

 

 

 


프로그래밍/개인홈페이지의 다른 글