spring boot // oauth2
--------------
참고프로젝트 jpa 메서드도 참고
https://github.com/codingspecialist/Springboot-Security-OAuth2.0-V2
oauth 세팅 유튜브
현재 프로젝트
https://github.com/jaybon1/springwork/tree/master/securityOAuthEx01
---------
프로젝트 생성 후 이클립스 내에서 의존성 추가하기
--
OAuth2 Client 선택 추가
---
구조
--
application.yml
네이밍전략 참고
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
--
WebMvcConfig.java
configureViewResolvers를 사용하면 뷰리졸버의 확장자를 원하는대로 설정 가능하다
이클립스는 .mustache를 기본 지원하지 않기 때문에 html로 바꿔서 이용하도록 하자
--
SecurityConfig.java
@EnableWebSecurity // 필터체인을 커스텀 한다는 어노테이션
@EnableGlobalMethodSecurity // 어노테이션 기반 보안을 적용 할 수 있다
public interface BankService {
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);
출처: https://yellowh.tistory.com/138 [노랭이의 공부공간]
WebSecurityConfigurerAdapter // 어댑터를 이용하면 원하는 보안기능만 커스텀 할 수 있다
--
추후에 만들 서비스인데 SecurityConfig 내부에서 사용하기 위해 @Autowired를 하였다
--
@Bean을 통해서 IOC 등록을 할 수 있다.
@Controller는 요청(request)가 올 때 IOC되므로 컨트롤러 이외의 IOC되는 공간에 Bean을 등록해야한다
(@Configuration 이나 @Component 등)
--
1. csrf 공격을 막는 기능을 비활성화 한다
2. /user 이후 모든 경로로 접속할 때 인증이 필요하다
3. /admin 이후 모든 경로로 접속할 때 ROLE_ADMIN 역할을 가지고 있어야 한다
(/admin** 이면 adminasdf 등의 경로로 접속할 때 )
4. 나머지 경로는 모두 허용한다
5. 폼로그인시 /login으로 리다이렉트 하고 로그인 요청시 /loginProc 주소로 이동
6. OAuth로그인시 설정
userInfoEndpoint() - OAuth2 로그인 성공 후 사용자 정보를 가져올 때의 설정들을 담당
userService(principalOauth2UserService) 소셜 로그인 성공 시 후속조치를 시행할 UserService 인터페이스의 구현체를 등록
--
해당 경로는 위의 시큐리티를 무시하고 접속하도록 함
UserRepository.java
JpaRepository를 상속하면 @Repository를 붙이지 않아도 IOC된다
JPA는 네이밍 전략으로 함수를 짤 수 있다는 점 참고 - 인터넷 검색
--
User.java
원래 모델에는 lombok의 @Data 를 사용하면 안된다 (연습용이기 때문에 사용)
@Id - 프라이머리키로 만들어줌(JPA)
@GeneratedValue - id 자동 증가 전략을 선택(JPA)
@CreationTimestamp - 타임스탬프 시간을 자동으로 넣어준다(JPA)
--
IndexController.java
@AuthenticationPrincipal // UserDetailsService에서 Return한 객체 를 파라메터로 직접 받아 사용할 수 있다
--
SecurityConfig에서 Bean으로 등록한 메서드를 DI 한다
--
비밀번호를 암호화하여 DB에 저장
--
@Secured // 컨트롤러에서 역할 체크를 하기 위해서 사용
--
PrincipalDetails.java
UserDetails는 Authentication 객체에 저장할 수 있는 유일한 타입이다 - 임플리먼트
OAuth2User는 OAuth2를 동시에 이용하기위해 임플리먼트
--
내부에 변수를 만들어도 되지만 User 타입 자체를 넣어도 무방하다
--
user에서 패스워드와 유저네임을 리턴
--
권한이 여러개일 수 있기 때문에 콜렉션으로 리턴한다
이것도 마찬가지로 SimpleGrantedAuthority라는 정해진 타입으로 만들어야 한다
--
OAuth2User를 임플리먼트 면 두개의 메서드를 오버라이딩 해야한다
getAttributes()는 google등 리소스 서버로부터 받는 회원정보를 담고 있다
PrincipalDetailsService.java
PrincipalDetailsService를 기본 UserDetailsService로 덮어 씌운다
loadUserByUsername()은 AuthenticationManager가 호출하는 메서드
--
OAuth2UserInfo.java
OAuth2 정보를 담을 인터페이스를 만든다
--
GoogleUserInfo.java
OAuth2UserInfo 타입을 임플리먼트 받아서 구글 전용으로 만든다
--
PrincipalOauth2UserService.java
스프링의 기본 DefaultOAuth2UserService를 상속 받는 커스텀 클래스를 만든다
토큰값으로 자원을 받아와서 세션에 등록한다
1. OAuth2 기능을 어떤 사이트(제공자)에서 사용했는지 확인
2. 제공자와 제공자의 ID를 받는다
Optional 타입을 이용하면 받은 객체가 null 이라도 내부에 저장되기 때문에 Optional 객체자체는 null이 아니라는 점을 이용할 수 있다
3. userOptional 내부의 객체가 null이 아니라면 내부 객체를 가져오고
null 이라면 User타입을 만들어서 DB에 저장한다