From 94b9871c1c3c470d5b7e93abbaa7704cd794d391 Mon Sep 17 00:00:00 2001 From: kim Date: Thu, 10 Dec 2020 03:41:45 +0900 Subject: [PATCH] google login -> auto join --- .../security1/config/SecurityConfig.java | 7 ++-- .../config/auth/PrincipalDetails.java | 19 ++++++---- .../config/auth/PrincipalDetailsService.java | 1 + .../oauth/PrincipalOauth2UserService.java | 38 +++++++++++++++++-- .../security1/controller/IndexController.java | 4 +- .../java/com/spring/security1/model/User.java | 2 + 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java b/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java index c6eba483..335ce3f8 100644 --- a/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java +++ b/spring-security/src/main/java/com/spring/security1/config/SecurityConfig.java @@ -1,7 +1,7 @@ package com.spring.security1.config; import com.spring.security1.config.oauth.PrincipalOauth2UserService; -import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -11,12 +11,11 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration -@RequiredArgsConstructor @EnableWebSecurity // 스프링 시큐리티 필터(SecurityConfig)가 스프링 필터 체인에 등록 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) // secured 어노테이션 활성화 , preAuthorized 활성화 public class SecurityConfig extends WebSecurityConfigurerAdapter { - - private final PrincipalOauth2UserService principalOauth2UserService; + @Autowired + private PrincipalOauth2UserService principalOauth2UserService; @Bean public BCryptPasswordEncoder encodePwd() { diff --git a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java index ad6b8e70..c7819d45 100644 --- a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java +++ b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetails.java @@ -22,21 +22,24 @@ import java.util.Map; public class PrincipalDetails implements UserDetails, OAuth2User { private User user; + private Map attributes; + // 일반 로그인 public PrincipalDetails(User user) { this.user = user; } + // OAuth 로그인인 + public PrincipalDetails(User user, Map attributes) { + this.user = user; + this.attributes = attributes; + } + // 해당 User의 권한을 리턴하는 곳 @Override public Collection getAuthorities() { Collection collection = new ArrayList<>(); - collection.add(new GrantedAuthority() { - @Override - public String getAuthority() { - return user.getRole(); - } - }); + collection.add((GrantedAuthority) () -> user.getRole()); return collection; } @@ -75,9 +78,9 @@ public class PrincipalDetails implements UserDetails, OAuth2User { @Override public Map getAttributes() { - return null; + return attributes; } - + @Override public String getName() { return null; diff --git a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java index f08ddba9..eb5e4042 100644 --- a/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java +++ b/spring-security/src/main/java/com/spring/security1/config/auth/PrincipalDetailsService.java @@ -18,6 +18,7 @@ public class PrincipalDetailsService implements UserDetailsService { private final UserRepository userRepository; + // 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다. @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User userEntity = userRepository.findByUsername(username); diff --git a/spring-security/src/main/java/com/spring/security1/config/oauth/PrincipalOauth2UserService.java b/spring-security/src/main/java/com/spring/security1/config/oauth/PrincipalOauth2UserService.java index 116dd925..e5c27e3e 100644 --- a/spring-security/src/main/java/com/spring/security1/config/oauth/PrincipalOauth2UserService.java +++ b/spring-security/src/main/java/com/spring/security1/config/oauth/PrincipalOauth2UserService.java @@ -1,5 +1,10 @@ package com.spring.security1.config.oauth; +import com.spring.security1.config.auth.PrincipalDetails; +import com.spring.security1.model.User; +import com.spring.security1.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; @@ -7,18 +12,45 @@ import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor public class PrincipalOauth2UserService extends DefaultOAuth2UserService { + private final BCryptPasswordEncoder bCryptPasswordEncoder; + private final UserRepository userRepository; + // 구글로부터 받은 userRequest 데이터에 대한 후처리 되는 함수 + // 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다. @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { System.out.println("userRequest: "+ userRequest.getClientRegistration()); // registrationId로 어떤oauth로 로그인했는지 확인가능. System.out.println("userRequest: "+ userRequest.getAccessToken().getTokenValue()); + + OAuth2User oAuth2User = super.loadUser(userRequest); // 구글 로그인 버튼 클릭 -> 구글 로그인 창 -> 로그인을 완료 -> code를 리턴(OAuth-Client 라이브러리) -> AccessToken 요청 // userRequest 정보 -> loadUser함수 -> 구글로 부터 회원 프로필 받아준다. - System.out.println("userRequest: "+ super.loadUser(userRequest).getAttributes()); + System.out.println("userRequest: "+ oAuth2User.getAttributes()); - OAuth2User auth2User = super.loadUser(userRequest); - return super.loadUser(userRequest); + String provider = userRequest.getClientRegistration().getRegistrationId(); // google + String providerId = oAuth2User.getAttribute("sub"); + String username = provider+"_"+providerId; + String password = bCryptPasswordEncoder.encode("패스워드"); + String email = oAuth2User.getAttribute("email"); + String role = "ROLE_USER"; + + User userEntity = userRepository.findByUsername(username); + + if(userEntity == null) { + userEntity = User.builder() + .username(username) + .password(password) + .email(email) + .provider(provider) + .providerId(providerId) + .role(role) + .build(); + userRepository.save(userEntity); + } + + return new PrincipalDetails(userEntity, oAuth2User.getAttributes()); } } diff --git a/spring-security/src/main/java/com/spring/security1/controller/IndexController.java b/spring-security/src/main/java/com/spring/security1/controller/IndexController.java index 63666394..9d5c86c5 100644 --- a/spring-security/src/main/java/com/spring/security1/controller/IndexController.java +++ b/spring-security/src/main/java/com/spring/security1/controller/IndexController.java @@ -54,9 +54,11 @@ public class IndexController { return "index"; } + // OAuth 로그인, 일반 로그인 모두 PrincipalDetails객체로 받을 수 있다. @ResponseBody @GetMapping("/user") - public String user() { + public String user(@AuthenticationPrincipal PrincipalDetails principalDetails) { + System.out.println("principalDetails :" + principalDetails.getUser()); return "user"; } diff --git a/spring-security/src/main/java/com/spring/security1/model/User.java b/spring-security/src/main/java/com/spring/security1/model/User.java index 0931c6c3..39cdcd92 100644 --- a/spring-security/src/main/java/com/spring/security1/model/User.java +++ b/spring-security/src/main/java/com/spring/security1/model/User.java @@ -2,6 +2,7 @@ package com.spring.security1.model; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; @@ -16,6 +17,7 @@ import java.sql.Timestamp; @Data @AllArgsConstructor @NoArgsConstructor +@Builder public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)