본문 바로가기

Server Programming/Spring Boot Full-Stack Programming

[스프링 풀스택 클론 코딩] 인증된 사용자와 미인증 사용자 분류

반응형

https://stackoverflow.com/questions/918393/whats-the-difference-between-interface-and-interface-in-java

 

What's the difference between interface and @interface in java?

I haven't touched Java since using JBuilder in the late 90's while at University, so I'm a little out of touch - at any rate I've been working on a small Java project this week, and using Intellij ...

stackoverflow.com

Java 프로그래밍 언어의 인터페이스 는 클래스가 구현해야 하는 동작을 지정하는 데 사용되는 추상 유형입니다. 프로토콜과 유사합니다. 인터페이스는 interface 키워드를 사용하여 선언됩니다.

 

@interface 는 고유한(사용자 정의) Java 주석을 만드는 데 사용됩니다. 주석은 Java 클래스 또는 인터페이스와 마찬가지로 자체 파일에 정의됩니다.

 

CurrentUser

package com.demo.account;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.security.core.annotation.AuthenticationPrincipal;

//런타임 유지를 위한 어노테이션
@Retention(RetentionPolicy.RUNTIME)
//파라미터에서 쓸수있도록 하는 어노테이션
@Target(ElementType.PARAMETER)
//인증된 사용자인지 판별하는 어노테이션
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : account")

//참조가능하도록 인터페이스로 설정
public @interface CurrentUser {

}

: @interface로 정의된 CurrentUser 클래스를 이용 현재 유저가 로그인한 유저인지 미인증 유저인지 판별한다.

 

MainController

@GetMapping("/")
	public String home(@CurrentUser Account account, Model model) {
		//인증한 사용자인 경우
		if(account !=null) {
			model.addAttribute(account);
		}
		return "index";

: 해당 @Interface를 이용해 -> 유저정보가 anonymousUser면 -> null로, null이 아니면 account객체를 모델에 담아 리턴

 

UserAccount

package com.demo.account;

import java.util.List;

import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;

import com.demo.domain.Account;

import lombok.Getter;

//getter 자동생성 어노테이션
@Getter
//User 인터페이스에서 상속
public class UserAccount extends User {

	//도메인 유저정보
	private Account account;
	
	//스프링 시큐리티 유저정보와 도메인 유저정보 연동
	
	public UserAccount(Account account) {
		super(account.getNickname(), account.getPassword(), List.of(new SimpleGrantedAuthority("ROLE_USER")));
		// 닉네임, 비밀번호, 권한
		this.account=account;
		//account에 설정
	}  
 
}

: 유저정보를 이용해 -> 정보를 가져와서  저장하는데,

판별한 정보를 토대로 인증된 사용자면, 스프링의 유저 정보와 도메인의 유저 정보를 엮어주는 역할을 한다.

 

 

해당 유저 정보가 null이고, 이메일인증을 받지 않은 이용자의 경우

-> 계정인증 이메일을 확인하라는 알림을 보낸다.

<div class="alert alert-warning" role="alert" th:if="${account != null &&!account.emailVerified}">
데모 가입을 완료하려면 <a href="#" th:href="@{/check-email}" class="alert-link">계정 인증 이메일을 확인</a>하세요.
</div>

  • @Retention은 해당 애노테이션이 언제까지 유지할지 알려주는 어노테이션
  • 자기 자신이 어느 시점까지 유효한지를 명시
    • RetentionPolicy를 이용
      • SOURCE
        • 주석처럼 사용 -> 소스 코드만 유지 컴파일하면 사라짐
      • CLASS
        • 기본값
        • 런타임에 클래스를 메모리로 읽어오면 사라짐
      • RUNTIME
        • 클래스를 메모리에 읽어와도 유지
        • 코드에서 이 정보를 이용해 로직을 실행가능

  • @Target 애노테이션은 해당 애노테이션이 어디에 사용될 수 있는가를 명시하는 어노테이션
  • 타입, 필드, 메서드, 파라미터, 생성자, 로컬변수, 어노테이션타입, 패키지, 타입파라미터 등

SecurityContextHolder : 클래스. 특정 전략에 따라 Security Context 영역을 관리하는 인터페이스입니다. 해당 클래스가 관리하는 SecurityContext 객체는 getter로 접근이 가능하다.(getContext() 메소드) 이는 현재 스레드 기준의SecurityContext를 반환한다.

SecurityContext : 인터페이스. Security Context 인터페이스. Authentication에 대한 접근 getter를 정의해놓음.

SecurityContextImpl : 클래스. SecurityContext 인터페이스를 구현한 객체. Authentication 객체에 대한 getter/setter를 정의해 놓은 객체. 해당 구현체를 통해 내부적으로 현재 스레드의(아마 1번의 request 요청일 것으로 생각되지만..) Security Context 를 생성하여 인증 후 Authentication 객체를 넣어놓는 역할을 한다.

Authentication : 인증 정보에 대한 부분을 정의해놓은 인터페이스. Principal과 Credentials, Authorities 에 대한 정의가 되어있다. 여러 구현체가 있지만 스프링 시큐리티 내용에서 UsernamePasswordAuthenticationToken 클래스를 활용


 - principal의 의미는 "인증되는 주체의 ID" 이고,

 - Credentials 은 "주체가 정확한지 증명하는 것"

 - Authorities는 아시다시피 "권한"의 내용입니다.

UserDetails : 사용자 정보(username, password 등)을 가지는 인터페이스. 이를 구현하여 실제 로그인에 사용할 클래스를 만들면 된다. 스프링 시큐리티 내부적으로 직접 사용하지는 않고 Authentication 으로 캡슐화하여 저장된다. 따라서 UserDetails 구현체의 정보는 Spring Security Context에 저장된 Authentication 객체가 가져간다고 볼 수 있다.

HandlerMethodArgumentResolver : 인터페이스. 특정 전략에 따라 한 request에서 넘어온 인자들을 메소드 파라미터로 해석할 수 있도록 도와줌. 

AuthenticationPrincipalArgumentResolver : 스프링 시큐리티에서 HandlerMethodArgumentResolver 를 구현한 구현체로 @AuthenticationPrincipal 어노테이션이 실제로 사용되는 부분.

 

 

출처

https://sas-study.tistory.com/410

반응형