Posts 스프링 시큐리티 OAuth
Post
Cancel

스프링 시큐리티 OAuth

스프링 시큐리티 구조

추후 설명 추가

OAuth 코드

SecurityConfig.java

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
@RequiredArgsConstructor
@EnableWebSecurity  // 스프링 시큐리티 설정 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final CustomOAuth2UserService customOAuth2UserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()    
                // URL별 권한 관리를 설정하는 옵션의 시작 antMatchers를 쓰기위해
                
                .antMatchers("/", "/css/**", "/images/**", "/js/**").permitAll()
                // 위의 URL들은 권한 없이도 접근 가능

                .antMatchers("/api/**").hasRole(Role.USER.name())
                // api로 시작하는 URL은 USER권한이 있는 사람만 접근 가능

                .anyRequest().authenticated()   // 설정한 값 이외의 URL은 로그인 된 사용자만 접근 가능
                .and()
                    .logout()
                        .logoutSuccessUrl("/")  // 로그아웃 성공시 해당 URL로 이동
                .and()
                    .oauth2Login()  // 로그인 기능에 대한 설정
                    .userInfoEndpoint() // 로그인 이후 사용자 정보를 가져올 때 설정
                        .userService(customOAuth2UserService); 
                        // customOAuth2UserService를 통해 사용자 정보를 가져온다
                        // customOAuth2UserService는 UserService의 구현체이다
    }
}


CustomOAuth2UserService.java

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
42
43
44
45
46
47
48
49
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
    //<OAuth2UserRequest, OAuth2User> 제네릭 문법으로 인자로 들어올 정확한 타입을 모르기 때문에 쓰임

    private final UserRepository userRepository;
    private final HttpSession httpSession;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2UserService delegate = new DefaultOAuth2UserService();
        OAuth2User oAuth2User = delegate.loadUser(userRequest);
        // UserInfo 끝점에서 사용자의 attributes를 가져온 후 OAuth2User를 통해 반환

        String registrationId = userRequest.getClientRegistration().getRegistrationId();
        // 현재 로그인 진행중인 서비스를 구분하는 코드 구글, 페이스북, 네이버 등 
        
        String userNameAttributeName = userRequest.getClientRegistration()
                .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
        // OAuth를 지원하는 서비스에서 사용자를 구분하기 위한 유니크 필드가 서로 다르기 때문에
        // 각 계정마다 유니크한 id값을 전달받기 위한 코드
        // 예를 들어 구글은 sub라는 필드가 유니크 키이고 네이버는 id라는 필드가 유니크 키이다

        OAuthAttributes attributes = OAuthAttributes
                .of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
        // OAuth2UserService를 통해 가져온 oAuth2User의 attribute를 담는 클래스

        User user = saveOrUpdate(attributes);
        // user에 값이 있다면 update, 값이 없다면 save를 한다

        httpSession.setAttribute("user", new SessionUser(user));
        // 세션에 사용자 정보를 저장하기 위한 DTO

        return new DefaultOAuth2User(
                Collections.singleton(
                        new SimpleGrantedAuthority(user.getRoleKey())),
                attributes.getAttributes(),
                attributes.getNameAttributeKey()
        );
        // DefaultOAuth2User에 유저 정보를 담아서 리턴
    }

    private User saveOrUpdate(OAuthAttributes attributes) {
        User user = userRepository.findByEmail(attributes.getEmail())
                .map(entity ->entity.update(attributes.getEmail()))
                .orElse(attributes.toEntity());
        return userRepository.save(user);
    }
}


백준 18881 Social Distancing II java

백준 6503 망가진 키보드 java

Comments powered by Disqus.