티스토리 뷰

반응형

이번 글에서는 Thymeleaf 에서 Spring Security 를 사용하는 방법에 대해 살펴보겠습니다. Spring Security 는 전역으로 한 번 설정해두었을 때 권한 별로 화면에서 보여지는 내용을 다르게 표시할 수 있습니다. 이를 위해서는 gradle 파일 내에 아래와 같이 의존성 주입을 해줍니다.

 

1. build.gradle

implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'

 

그리고 namespace 라는 내용이 있습니다. html 태그 안에 추가를 하는 내용이고, 네임스페이스에서 특정 타임리프의 문법을 사용할 것을 선언합니다.

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

우리는 타임리프 문법에서 tag property 앞에 'th:'라는 타임리프 네임스페이스를 이미 쓰고있었습니다. 바로 xmlns:th 선언이 되어 있기 때문입니다. 

이제 시큐리티를 타임리프에서 사용할 준비가 끝났습니다. 다음으로는 사용 방법과 예시를 한 번 살펴보겠습니다.

 

2. Principal 클래스 참조 사용 방법

사용하는 방법은 타임리프와 같습니다. 'th:value', 'th:text' 와 같이 사용하던대로 'sec:authentication' 를 앞에 붙이기만 하면 됩니다. 

<span sec:authentication="name"></span>
문법 인터페이스 객체 내용
sec:authentication="name" Principal username 을 리턴

Principal 객체는 아래와 같이 선언된 인터페이스입니다. 

package java.security;

import javax.security.auth.Subject;

public interface Principal {
    public boolean equals(Object another);
    public String toString();
    public int hashCode();
    public String getName();
}

 

아래의 인터페이스를 상속받아 구현 클래스를 만들면 더 호환이 좋게 사용할 수 있습니다.

import java.security.Principal;

@Getter
@NoArgsConstructor
public class UserPrincipal implements Principal {

    private final Integer id;
    private String name;
    private String email;
    private final Collection<? extends GrantedAuthority> authorities;

    public UserPrincipal(Integer id, String name, String email,
        Collection<? extends GrantedAuthority> authorities) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.authorities = authorities;
    }
}

그리고 위에서 구현한 객체는 아래처럼 사용가능한 문법으로 바뀝니다.

ID: <span sec:authentication="principal.id"></span><br>
Name: <span sec:authentication="principal.name"></span><br>
이메일: <span sec:authentication="principal.email"></span>

 

여기서 IntelliJ 의 경우 principal 객체를 찾기 위해 Cmd 키를 누르고 클릭을 하게 되면 아래 Authentication 객체의 getPrincipal() 메소드가 찍히게 됩니다. 

package org.springframework.security.core;

import java.io.Serializable;
import java.security.Principal;
import java.util.Collection;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    Object getCredentials();
    Object getPrincipal();
    boolean isAuthenticated();
    void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

 


3. SecurityExpressionRoot 참조하기

이번에는 아래의 태그들을 사용하는 법을 알아보겠습니다.

<span sec:authorize="isAuthenticated()"></span> // 로그인하여 인증된 사용자
<span sec:authorize="isAnonymous()"></span> // 로그인하지 않은 사용자
<span sec:authorize="hasRole('ROLE_ADMIN')"></span> // ROLE_ADMIN을 가진 사용자
<span sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER')"></span> // ROLE_ADMIN 또는 
ROLE_MANAGER 권한중 하나 이상 가진 사용자

해당 클래스의 구현체는 아래의 추상클래스에 표시되어 있습니다.

package org.springframework.security.access.expression;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

/**
 * Base root object for use in Spring Security expression evaluations.
 *
 * @author Luke Taylor
 * @since 3.0
 */
public abstract class SecurityExpressionRoot implements SecurityExpressionOperations

 

이를 알기 위해서는 가장 먼저 Spring Security 의 Role에 대하여 알아야 합니다. Spring Security는 로그인에 성공하게 되어 인증이 완료되면 Set<Role> 이라는 권한을 가지게 되는데 이 부분은 시큐리티에 대한 글을 따로 올리도록 하겠습니다.

 

오늘은 이렇게  Spring Security의 내용과 Thymeleaf 를 연관짓는 방법에 대해 간단히 끄적여보았습니다. 스프링 시큐리티는 알면 알수록 편리하게 인증을 도와주는 도구로 활용이 가능한 것 같습니다. 조금 더 파봐야겠습니다!

반응형
댓글
공지사항