google login -> auto join
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
package com.spring.security1.config;
|
package com.spring.security1.config;
|
||||||
|
|
||||||
import com.spring.security1.config.oauth.PrincipalOauth2UserService;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
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;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@RequiredArgsConstructor
|
|
||||||
@EnableWebSecurity // 스프링 시큐리티 필터(SecurityConfig)가 스프링 필터 체인에 등록
|
@EnableWebSecurity // 스프링 시큐리티 필터(SecurityConfig)가 스프링 필터 체인에 등록
|
||||||
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) // secured 어노테이션 활성화 , preAuthorized 활성화
|
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) // secured 어노테이션 활성화 , preAuthorized 활성화
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
@Autowired
|
||||||
private final PrincipalOauth2UserService principalOauth2UserService;
|
private PrincipalOauth2UserService principalOauth2UserService;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public BCryptPasswordEncoder encodePwd() {
|
public BCryptPasswordEncoder encodePwd() {
|
||||||
|
|||||||
@@ -22,21 +22,24 @@ import java.util.Map;
|
|||||||
public class PrincipalDetails implements UserDetails, OAuth2User {
|
public class PrincipalDetails implements UserDetails, OAuth2User {
|
||||||
|
|
||||||
private User user;
|
private User user;
|
||||||
|
private Map<String, Object> attributes;
|
||||||
|
|
||||||
|
// 일반 로그인
|
||||||
public PrincipalDetails(User user) {
|
public PrincipalDetails(User user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuth 로그인인
|
||||||
|
public PrincipalDetails(User user, Map<String, Object> attributes) {
|
||||||
|
this.user = user;
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
|
||||||
// 해당 User의 권한을 리턴하는 곳
|
// 해당 User의 권한을 리턴하는 곳
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
Collection<GrantedAuthority> collection = new ArrayList<>();
|
Collection<GrantedAuthority> collection = new ArrayList<>();
|
||||||
collection.add(new GrantedAuthority() {
|
collection.add((GrantedAuthority) () -> user.getRole());
|
||||||
@Override
|
|
||||||
public String getAuthority() {
|
|
||||||
return user.getRole();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,9 +78,9 @@ public class PrincipalDetails implements UserDetails, OAuth2User {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getAttributes() {
|
public Map<String, Object> getAttributes() {
|
||||||
return null;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class PrincipalDetailsService implements UserDetailsService {
|
|||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
|
||||||
|
// 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다.
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
User userEntity = userRepository.findByUsername(username);
|
User userEntity = userRepository.findByUsername(username);
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.spring.security1.config.oauth;
|
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.DefaultOAuth2UserService;
|
||||||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
|
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||||
@@ -7,18 +12,45 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
|
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
|
||||||
|
|
||||||
|
private final BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
// 구글로부터 받은 userRequest 데이터에 대한 후처리 되는 함수
|
// 구글로부터 받은 userRequest 데이터에 대한 후처리 되는 함수
|
||||||
|
// 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다.
|
||||||
@Override
|
@Override
|
||||||
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
|
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
|
||||||
System.out.println("userRequest: "+ userRequest.getClientRegistration()); // registrationId로 어떤oauth로 로그인했는지 확인가능.
|
System.out.println("userRequest: "+ userRequest.getClientRegistration()); // registrationId로 어떤oauth로 로그인했는지 확인가능.
|
||||||
System.out.println("userRequest: "+ userRequest.getAccessToken().getTokenValue());
|
System.out.println("userRequest: "+ userRequest.getAccessToken().getTokenValue());
|
||||||
|
|
||||||
|
OAuth2User oAuth2User = super.loadUser(userRequest);
|
||||||
// 구글 로그인 버튼 클릭 -> 구글 로그인 창 -> 로그인을 완료 -> code를 리턴(OAuth-Client 라이브러리) -> AccessToken 요청
|
// 구글 로그인 버튼 클릭 -> 구글 로그인 창 -> 로그인을 완료 -> code를 리턴(OAuth-Client 라이브러리) -> AccessToken 요청
|
||||||
// userRequest 정보 -> loadUser함수 -> 구글로 부터 회원 프로필 받아준다.
|
// userRequest 정보 -> loadUser함수 -> 구글로 부터 회원 프로필 받아준다.
|
||||||
System.out.println("userRequest: "+ super.loadUser(userRequest).getAttributes());
|
System.out.println("userRequest: "+ oAuth2User.getAttributes());
|
||||||
|
|
||||||
OAuth2User auth2User = super.loadUser(userRequest);
|
String provider = userRequest.getClientRegistration().getRegistrationId(); // google
|
||||||
return super.loadUser(userRequest);
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,11 @@ public class IndexController {
|
|||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuth 로그인, 일반 로그인 모두 PrincipalDetails객체로 받을 수 있다.
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@GetMapping("/user")
|
@GetMapping("/user")
|
||||||
public String user() {
|
public String user(@AuthenticationPrincipal PrincipalDetails principalDetails) {
|
||||||
|
System.out.println("principalDetails :" + principalDetails.getUser());
|
||||||
return "user";
|
return "user";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.spring.security1.model;
|
|||||||
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.hibernate.annotations.CreationTimestamp;
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
@@ -16,6 +17,7 @@ import java.sql.Timestamp;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
public class User {
|
public class User {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
Reference in New Issue
Block a user