구글 oauth 설정

console.developers.google.com/apis

 

Google Cloud Platform

하나의 계정으로 모든 Google 서비스를 Google Cloud Platform을 사용하려면 로그인하세요.

accounts.google.com

 

 

 

앱 : 내서버

사용자 데이터 : 구글이 들고 있는 사용자 정보

 

 

아무것도 체크하지말고 만들기 클릭

 

스코프 기억

 

입력없이 저장

 

동의화면 만들어짐

 

사용자 인증 정보 만들기 다시 선택

 

 

 

 

CORS정책 : 다른 도메인에서 오는 자바스크립트 요청을 막음(이 수업에선 안쓸 것)

 

이것을 사용할 것

http://localhost:8080/login/oauth2/code/google

표준 주소이기 때문에 google 부분만 바꾸면서 사용

 

 

----

 

ROLE 만들기

 

우리는 이렇게 사용할 것 (ROLE이 하나뿐이라서)

 

ROLE_ : 프리픽스로서 스프링 시큐리티에서 약속된 규칙

 

권한 확인 방법은 둘 중 하나를 사용 할 수 있다

.hasAnyRole()

.access() - or and 를 사용 할 수 있다

.hasAuthority
.hasAnyAutority 등을 이용하면 and or을 쓸 수 없기 때문에 사용을 비추

-----

 

 

.antMatchers("/admin/**")를 모두 막아두고
세부적으로 /admin/1은 열어두고 싶을때

1. 시큐리티에서 하는 방법

정적인 파일은 ignoring()

 

2. 컨트롤러에서 하는 방법

SecurityConfig.java

IndexController.java

 

@PostAuthorize도 참고

 

 

ROLE이 다른 사람이면 거부됨

 

 

ROLE이 맞다면 허용

----

 

 

머스태치 html확장자로 이용하기

 

 

컨피그를 어노테이션 하고
configureViewResolvers를 오버라이딩

package com.jaybon.securityEx01.config;

import org.springframework.boot.web.servlet.view.MustacheViewResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
	
	@Override // 뷰리졸버 설정
	public void configureViewResolvers(ViewResolverRegistry registry) {
		
		// 머스태치 리졸버 설정
		MustacheViewResolver resolver = new MustacheViewResolver();
		
		resolver.setCharset("utf-8");
		resolver.setContentType("text/html;charset=utf-8");
		resolver.setPrefix("classpath:/templates/"); // 뷰의 위치
		resolver.setSuffix(".html");
		
		registry.viewResolver(resolver);
	}
}

 

---------------------------------

 

springboot 21강 - ResponseEntity와 @Valid와 @BindResult 사용하기

https://blog.naver.com/getinthere/221795214908

 

springboot 21강 - ResponseEntity와 @Valid와 @BindResult 사용하기

간단한 테스트를 위해 아래와 같은 의존성 사용모든 Controller는 결과값을 return한다. 이 때 Get 요청...

blog.naver.com

--

 

참고 리파지토리

https://github.com/codingspecialist/Springboot-Jpa-AOP-Valid-RestDoc

 

codingspecialist/Springboot-Jpa-AOP-Valid-RestDoc

Contribute to codingspecialist/Springboot-Jpa-AOP-Valid-RestDoc development by creating an account on GitHub.

github.com

 

현재 프로젝트 (아래 코드 설명과 같이 보려면 이곳을 확인)

https://github.com/jaybon1/springwork/tree/master/validEx01

 

jaybon1/springwork

Contribute to jaybon1/springwork development by creating an account on GitHub.

github.com

 

 

프로젝트 생성

 

 

밸리데이션 추가(위에서 추가해도되고 따로 이렇게 추가해도됨)

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>

 

Spring boot DevTools -> 코드변경시 바로 리로드 및 캐시 사용안하는 등 편리하다

 

구조

---

 

 

application.yml

--

 

 

ProjectTask.java

의존성에 추가한 validation을 이용한다

@NotBlank - 널값이나 빈값으로 올경우 잡아낸다

@Size - 내용의 길이를 확인하여 맞지 않는 경우 잡아낸다

@Email - 이메일 형식에 맞지 않으면 잡아낸다

이외에도 다양한 어노테이션이 있으니 확인

----

 

 

StatusCode.java

상태값을 설정한다 (기존의 상태값을 이용하려면 HTTP상태코드 검색)

--

 

 

ProjectTaskRepository.java

Jpa리파지토리를 상속

---

 

 

RespDto.java

안드로이드나 리액트 등 데이터를 리턴받는 뷰 쪽에서 요청이 올 경우 돌려보낼 데이터

제네릭을 이용하여 데이터를 변화시켜 보내준다

--

 

 

BindingAdvice.java

AOP로 등록하기 위해 @Aspect 를 붙여준다

IOC를 위해 @Component를 붙여준다

---

 

JoinPoint는 핵심로직이다 (즉 Controller의 실행될 메서드)

PointCut은 공통기능의 위치를 말한다

Weaving은 공통기능을 배치하는 것을 말한다

Advice는 공통기능을 말한다

@Before는 핵심로직전  @After는 핵심로직후  @Around (Before After 바깥)

@Before @After 는 request를 못들고 온다

@Around는 JoinPoint 메서드의 컨텍스트를 들고 올 수 있다(request 등)

excution within 등 확인 

---

 

execution 내용 설명

*은 메서드명 
(..) 매개변수 0개이상 (*) 매개변수 1개 ->  *(..) = 모든 메서드, 모든 매개변수 개수

주소의 *는 모든 값 -> com.jaybon.validEx01.test.* = test하위의 모든 기능

.*Controller 모든 하위 Controller -> com.jaybon.validEx01..*Controller.*(..) = validEx01의모든 하위컨트롤러의 모든메서드

--

 

1. proceedingJoinPoint는 실행할 Controller 메서드의 정보이다.

2. proceedingJoinPoint의 매개변수들을 가져온다

3. 매개변수 중 BindingResult가 있고 에러가 났다면 요청실패 객체를 리턴한다

4. 에러가 나지 않았다면 그대로 메서드를 진행한다

---

 

 

BindControllerTest.java

AOP테스트를 위한 컨트롤러

--

 

테스트 결과

--

 

 

ProjectTaskController.java

@Autowired는 IOC 된 클래스에서만 작동한다(즉 @Component 및 관련 어노테이션을 붙이지 않은 클래스에서는 작동하지 않음)

AOP로 validation을 하기 위해서는 체크할 매개변수 입력데이터 앞에 @Valid를 붙여주고

BindingResult를 매개변수 마지막에 넣어주도록 하자

ResponseEntity<?>로 상태 값 및 데이터 리턴

--

 

JPA의 save 는 리턴값이 엔티티다 (넣은 값을 바로 찾을 수 있다는 것)

다만 위 코드는 연습용으로, 보통은 저장한 값을 클라이언트에게 리턴하지 않는다

repuestProjectTask 는 유저가 입력한 값

entityProjectTask 는 데이터베이스에서 가져온 값

구분해야됨

--

 

포스트맨으로 요청 및 결과

 

콘솔창 확인

---

 

잘못된 형식으로보낼 경우

 

JPA 하이버네이트가 작동하지 않고 요청실패 객체를 리턴했다는 것을 알 수 있다

 

 

 

 

 

 

 

아래 프로젝트를 참고하여 진행 (내용이 약간다름)

https://github.com/codingspecialist/Springboot-Security-JWT

 

codingspecialist/Springboot-Security-JWT

Contribute to codingspecialist/Springboot-Security-JWT development by creating an account on GitHub.

github.com

 

위 프로젝트 연구

https://ondolroom.tistory.com/690

 

spring boot // Springboot-Security-JWT 프로젝트 분석

연구할 프로젝트 https://github.com/codingspecialist/Springboot-Security-JWT codingspecialist/Springboot-Security-JWT Contribute to codingspecialist/Springboot-Security-JWT development by creating an..

ondolroom.tistory.com

 

사전 정보

https://ondolroom.tistory.com/687

 

spring boot // 토큰 기반 / JWT 정보

아래 사이트를 참고하여 정리합니다 https://velopert.com/2350 [JWT] 토큰(Token) 기반 인증에 대한 소개 | VELOPERT.LOG 소개 토큰(Token) 기반 인증은 모던 웹서비스에서 정말 많이 사용되고 있습니다. 여러분.

ondolroom.tistory.com

 

현재 프로젝트 (아래 코드 설명을 참고하려면 이곳을 확인)

https://github.com/jaybon1/springwork/tree/master/jwtEx01

 

jaybon1/springwork

Contribute to jaybon1/springwork development by creating an account on GitHub.

github.com

 

프로젝트 명 생성

 

 

필요한 의존성 추가

---------

 

프로젝트 구조

----------

 

 

pom.xml

JWT 의존성 추가

		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>3.4.1</version>
		</dependency>

--------

 

application.yml

----

 

RestApiController.java

@RequestMapping("api/v1") // 공통 진입경로 확인

@Autowired 를 사용하지 않고 DI할 것들에 final 붙이고 @RequiredArgsConstructor를 붙여주면 똑같은 효과

---------

 

 

SecurityConfig.java

메서드를 IOC 하기 위한 @Bean

 

1. STATELESS로 만들면 jsessoinId를 만들지 않는다

2. /login 경로로 접근시 해당필터에 걸리게 된다

3. 해당 경로로 접근시 ROLE이 맞는 사람만 접속 하도록 한다

.anyRequest().permitAll() 나머지 요청은 모두 허용한다

-----------

 

CorsConfig.java

cors()옵션 - 기타도메인의 자바스크립트 요청을 거부

@CrossOrigin은 컨트롤러 클래스가 아닌 메서드에 거는 것을 추천

전역적으로 설정하려면 아래와 같이 파일 생성하여 입력

 

 

User.java

원래 model에는 setter를 달면 안된다 - DTO를 이용하자

--

 

LoginRequestDto.java

로그인 데이터를 전송하기위한 DTO

 

 

PrincipalDetails.java

UserDetails를 상속하기 위한 클래스

User 객체를 컴포지션 한다

()-> 화살표 함수를 사용하면 GrantedAuthority와 관련된 클래스를 지정하지 않고도 자동으로 만들 수 있다

---------

 

 

PrincipalDetailsService.java

DB에서 유저를 검색하여 있으면 UserDetails를 리턴한다

-------

 

 

JwtAuthenticationFilter.java

------

 

1. attemptAuthentication은 인증 요청시에 실행 된다 (/login)

2. ObjectMapper는 데이터가 어떠한 형식으로 들어오더라도 값을 변환하여 객체에 담아준다

3. attemptAuthentication을 커스텀하면 UsernamePasswordAuthenticationToken을 직접 만들어 줘야한다

4. 아래 주석 참고

--------

 

1. Authentication 객체에서 PrincipalDetails를 가져온다

2. 클레임들을 삽입하고 암호알고리즘을 추가하여 JWT토큰을 만든다

3. 만들어진 토큰을 헤더에 넣는다

-------

 

 

JwtAuthorizationFilter.java

BasicAuthenticationFilter는 헤더전문 필터

--

 

팁 : 내가 new 한 클래스는 Autowired가 안된다

매개변수로 userRepository를 받아서 전역변수에 담아준다

----

 

1. 인증필터가 끝나면 인가필터로 넘어오는 것

2. 헤더값에 JWT토큰이 있는지 확인하여 없으면 돌려보낸다

3. 토큰이 있다면 JWT토큰에서 베리어와 패딩을 뺀 순수한 토큰값을 가져온다

---

 

토큰 검증하기
시크릿 키값과 함께 암호화된 파일을 풀어서 유저네임을 가져온다
암호화를 풀고 유저네임을 가져온 것 자체가 검증이 끝났다는 것

---

 

인가 1번방식

1. 위에서 검증이 끝난 유저네임으로 리파지토리에서 데이터를 받아
UserDetails 를 상속받은 PrincipalDetails를 만든다

2. UsernamePasswordAuthenticationToken을 만들고
authenticationManager를 사용하지 않고 usernamePasswordAuthenticationToken를 이용하여 Authentication 제작

3. 시큐리티 세션저장공간에 authentication을 넣는다.

----

 

인가 2번 방식

1. 위에서 검증이 끝난 유저네임으로 리파지토리에서 데이터를 받아 sessionUser라는 DTO에 넣어준다

2. 시큐리티세션(authentication)이 아닌 일반세션에 넣어준다

----

 

컨트롤러에서 일반세션 테스트용 메서드를 매핑한다

--

 

콘솔창 확인

--

 

포스트맨 확인

--

 

인가 3번 방식


클레임에 ROLE을 넣어서 바로어썬티케이션 만들기
(이렇게 만들면 리파지토리에서 유저를 가져올 필요도 없다 / 토큰에서 인증한 데이터로 만들면되기 때문)

--

 

인가 4번 방식

1번 방식을 개선한 방식

----

 

마지막으로 필터체인으로 다시 돌아간다

 

 

@inject : 모든 자바코드에서 적용가능

@autowired : 스프링 전용 어노테이션

autowired의 기본원리는 생성자를 만드는 것이다

IOC된 객체들을 찾아서 DI해주는 것

--------------

 

안드로이드를 예시로 JWT 진행순서

레트로핏 post 요청 

-> jwt필터에서 로그인프로세스 요청을 낚아챔

-> UserDetailsService타서 DB에서 확인 + 어썬티케이션 생성 되는것 확인 + 로그인

-> 세션을 만드는게 아니라 토큰을 만듬

-> 토큰에 권한을 부여 (인증+권한 - 슈도코드)

-> 토큰을 리스폰스 (헤더에 담아서 보냄) - 헤더 안에 authorization 필드 생성 

header: {
	authorization:
		"베리어 토큰"
}

base64로 인코딩, 디코딩 (헤더에 담고 인코딩 디코딩 하는 것은 전부 규칙이며 커스텀 가능)

 

-> 재요청시 토큰을 실어서 서버로 보냄

-> 서버에서 내가 만든 토큰인지 확인 (시크릿 키값으로 확인 = 서명검증)

 

토큰은 탈취 당할 수 있기 때문에 유효시간이 있다

토큰을 탈취 당하지 않기 위해서는 SSL HTTPS 를 써야함

-

+ Recent posts