1. Security 설정
스프링 시큐리티를 사용하는데 쓸 기능들을 명시해준다
@RequiredArgsConstructor
// 스프링 시큐리티 설정 활성화
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable().disable()
.authorizeRequests() //URL 별 권한 관리 옵션
.antMatchers("/","/css/**","/images/**","/js/**","/api/**").permitAll() // 모든 사용자
.antMatchers("/api2/**").hasRole(Role.USER.name()) // 유저 들만
.anyRequest().authenticated() //설정값 이외의 URL
.and()
.logout()
.logoutSuccessUrl("/") //로그아웃 성공시 홈으로 이동
.invalidateHttpSession(true)
.and()
.oauth2Login() // OAuth 2 로그인 기능 설정
.userInfoEndpoint()// 로그인 성공이후 사용자 정보를 가져올때의 설정
.userService(customOAuth2UserService);// 로그인 성공시 후속 조치할 userService 구현체 등록
}
}
2. Service 구현
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
private final HttpSession httpSession;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();//네이버 로그인인지 구글로그인인지 서비스를 구분해주는 코드
String userNAmeAttributeName = userRequest.getClientRegistration().getProviderDetails()
.getUserInfoEndpoint().getUserNameAttributeName(); //OAuth2 로그인 진행시 키가 되는 필드값 프라이머리키와 같은 값 네이버 카카오 지원 x
OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNAmeAttributeName, oAuth2User.getAttributes()); //OAuth2UserService를 통해 가져온 데이터를 담을 클래스
User user = saveOrUpdate(attributes);
httpSession.setAttribute("user", new SessionUser(user));
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRoleKey())),
attributes.getAttributes(),
attributes.getNameAttributeKey());
}
private User saveOrUpdate(OAuthAttributes attributes) {
User user = userRepository.findByEmail(attributes.getEmail())
.map(entity -> entity.update(attributes.getName(), attributes.getPicture()))
.orElse(attributes.toEntity());
return userRepository.save(user);
}
}
3. Attribute 정의
@Getter
public class OAuthAttributes {
private Map<String,Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;
@Builder
public OAuthAttributes(Map<String,Object> attributes, String nameAttributeKey, String name, String email, String picture){
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}
//사용자 정보는 Map이기 때문에 변경해야함
public static OAuthAttributes of(String registrationId, String userNameAttributeName, Map<String,Object> attributes){
return ofGoogle(userNameAttributeName, attributes);
}
public static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String,Object> attributes){
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
public User toEntity(){
return User.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
}
- 서비스에서 사용되는 attribute을 정의한 것
'JAVA > Spring Boot' 카테고리의 다른 글
(Spring Boot) 동작 원리 (0) | 2021.08.10 |
---|---|
(스프링 부트) 커스텀어노테이션으로 중복코드 방지 (0) | 2021.07.14 |
(Spring Boot)TestRestTemplate null request Error (0) | 2021.07.12 |
(Spring Boot)Entity에 있는 리스트 조회 제한하기 (0) | 2021.07.08 |
(디버깅)일대다 양방향 Response Error (0) | 2021.07.02 |