Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ repositories {

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
// implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'

compileOnly 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.studymouse.studymouseserver.security;

import com.studymouse.studymouseserver.security.dto.AccessUser;
import com.studymouse.studymouseserver.security.dto.OAuthAttributes;
import com.studymouse.studymouseserver.user.User;
import com.studymouse.studymouseserver.user.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.Collections;

@RequiredArgsConstructor
@Service
public class CustomOAuthUserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {

private final UserRepository userRepository;
private final HttpSession httpSession;

@Override
public OAuth2User loadUser(final OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService delegate = new DefaultOAuth2UserService();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 왜 빈으로 주입 안받음? 못받나??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

방금까지 OAuth 갑자기 안되는것 같아서 한참 헤매다가 내가 착각해가지고 삽질해서 지금 확인했는데 ㅠㅠ

일단 OAuth2 적용하는것은 동욱님 책 참고하면서 하는 중인데 빈으로 주입 받아서 하려니까 오류나서 안된다고 나오네....
예전에 professorlol 프로젝트 확인해보니까 지금 내가 구현한건 인터페이스 implements 해서 구현했고, professorlol 은 저 DefaultOAuth2UserService 상속받아서 구현해서 저렇게 가져오지않고 super.loadUser로 값을 가져오는 식으로 구현했더라고
일단 계속 확인해볼께 ㅠ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잉구ㅠㅜ 화이팅 오빠 시간 많으니까!! 정 하가 안되면 금토일 같이 봐도 좋으니ㅠㅜ 쉬엄쉬엄해여

OAuth2User oAuth2User = delegate.loadUser(userRequest);

String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();

OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());

User user = save(attributes);

httpSession.setAttribute("user", new AccessUser(user));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 의존관계가 OauthAttribute가 User를 만들고 User가 AccessUser를 만드는건가??
저 httpSession은 어디에 필요해??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OauthAttribute가 소셜 로그인 했을때 구글에서 반환하는 값으로 User를 만들고 DB에 저장한다음에, AccessUser로 세션 저장하는 거인데 로그인 하고 단어 저장할때마다 세션 정보 필요할것 같아서 만들어 두었엉


return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRoleKey())),
attributes.getAttributes(),
attributes.getNameAttributeKey()
);
}

private User save(final OAuthAttributes attributes) {
User user = userRepository.findByEmail(attributes.getEmail())
.orElse(attributes.toEntity());

return userRepository.save(user);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.studymouse.studymouseserver.security;

import com.studymouse.studymouseserver.user.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig {

@RequiredArgsConstructor
@EnableGlobalMethodSecurity(securedEnabled = true)
static public class SecurityMajorConfig extends WebSecurityConfigurerAdapter {

private final CustomOAuthUserService customOAuthUserService;

@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/api/word/**").hasRole(Role.USER.name())
.anyRequest().permitAll()
.and()
.logout().logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuthUserService);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.studymouse.studymouseserver.security.dto;

import com.studymouse.studymouseserver.user.User;
import lombok.Getter;

@Getter
public class AccessUser {

private String name;
private String email;
private String picture;

public AccessUser(final User user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정적 팩터리로 바꾸면 좋을것같아여!

this.name = user.getName();
this.email = user.getEmail();
this.picture = user.getPicture();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.studymouse.studymouseserver.security.dto;

import com.studymouse.studymouseserver.user.Role;
import com.studymouse.studymouseserver.user.User;
import lombok.Builder;
import lombok.Getter;

import java.util.Map;

@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;

@Builder
public OAuthAttributes(final Map<String, Object> attributes, final String nameAttributeKey, final String name, final String email, final String picture) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private 으로 해주세여

this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}


public static OAuthAttributes of(final String registrationId, final String userNameAttributeName, final Map<String, Object> attributes) {
return ofGoogle(userNameAttributeName, attributes);
}

private static OAuthAttributes ofGoogle(final String userNameAttributeName, final 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.USER)
.build();
}
}