반응형
이메일 인증을 하지 않은 사용자에게 메시지
<!-- 로그인하지 않은 사용자에 대한 메시지, 계정정보를 넘겨줘야한다.-->
<div class="alert alert-warning" role="alert" th:if="${account != null &&!account.emailVerified}">
데모 가입을 완료하려면 <a href="#" th:href="@{/check-email}" class="alert-link">계정 인증 이메일을 확인</a>하세요.
</div>
MainController
package com.demo.main;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.demo.account.CurrentUser;
import com.demo.domain.Account;
@Controller
//첫 페이지로 가는 요청 핸들러 작성
public class MainController {
//스프링이 제공하는 @AuthenticationPrincipal를 동적으로 사용하기 위해
//익명일 경우 null로 익명이 아닐 경우 account 객체로 사용
@GetMapping("/")
public String home(@CurrentUser Account account, Model model) {
//인증한 사용자인 경우
if(account !=null) {
model.addAttribute(account);
}
return "index";
//login 메서드에는 account라는 프로퍼티가 없기 때문에 중간 매개자 UserAccount 작성
//도메인의 유저정보와 스프링 시큐리티 유저정보의 연결고리
}
}
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 {
}
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에 설정
}
}
기존 AccountService의 login 메서드
public void login(Account account) {
// TODO Auto-generated method stub
//스프링 시큐리티에서 컨텍스트 홀더라는 기능을 이용해 간편하게 로그인
//토큰을 이용해 로그인 -> 토큰은, 닉네임, 패스워드, 권한으로 이루어져 있다.
UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(
account.getNickname(),
//nickname이 Principal로 인증된 사용자 여부를 가리는 매개체가 된다.
account.getPassword(),
List.of(new SimpleGrantedAuthority("ROLE USER")));
//권한 목록을 받아서 ROLE USER로 설정
// SecurityContext context =SecurityContextHolder.getContext();
// context.setAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(token);
//해당 토큰을 인증에 사용 ->정석적으로는 form인증할때 username, password를 이용해 AuthenticationManger를 통해 인증
// //정석적인 코드 -> 실제 비밀번호를 접근해야 하므로 사용하기 어렵다.
// UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
// Authentication authentication = authenticationManager.authenticate(token);
// SecurityContext context = SecurityContextHolder.getContext();
// context.setAuthentication(authentication);
}
변경한 AccountService의 login 메서드
public void login(Account account) {
// TODO Auto-generated method stub
//스프링 시큐리티에서 컨텍스트 홀더라는 기능을 이용해 간편하게 로그인
//토큰을 이용해 로그인 -> 토큰은, 닉네임, 패스워드, 권한으로 이루어져 있다.
UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(
new UserAccount(account),
//principal 객체로 변환
account.getPassword(),
List.of(new SimpleGrantedAuthority("ROLE USER")));
//권한 목록을 받아서 ROLE USER로 설정
// SecurityContext context =SecurityContextHolder.getContext();
// context.setAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(token);
//해당 토큰을 인증에 사용 ->정석적으로는 form인증할때 username, password를 이용해 AuthenticationManger를 통해 인증
// //정석적인 코드 -> 실제 비밀번호를 접근해야 하므로 사용하기 어렵다.
// UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
// Authentication authentication = authenticationManager.authenticate(token);
// SecurityContext context = SecurityContextHolder.getContext();
// context.setAuthentication(authentication);
}
반응형
'Server Programming > Spring Boot Full-Stack Programming' 카테고리의 다른 글
[스프링 풀스택 클론 코딩 - 회원가입] (1-17) 가입 확인 이메일 재전송 (0) | 2022.08.30 |
---|---|
[스프링 풀스택 클론 코딩] 인증된 사용자와 미인증 사용자 분류 (0) | 2022.08.30 |
[스프링 풀스택 클론 코딩 - 회원가입] (1-15) 첫 페이지 보완 (0) | 2022.08.30 |
[스프링 풀스택 클론 코딩] npm 라이브러리를 이용한 아이콘 추가 / jdenticon을 이용한 이미지 생성 (0) | 2022.08.30 |
[스프링 풀스택 클론 코딩] 타임리프의 fragment 기능 (0) | 2022.08.29 |