쉽게 쉽게

[Spring] Spring Security 구현 (3) - 활용 본문

개발공부/Spring

[Spring] Spring Security 구현 (3) - 활용

곱마2 2024. 12. 20. 13:39
반응형

▤ 목차

스프링 시큐리티를 통해 로그인을 성공 후 로그인 정보를 가져오는 방법에 대해 공부하고자 했다.

1. 로그인 정보 사용법

 로그인 정보를 사용하는 방법은 두 가지 정도로 생각했다.

  • 공통적으로 사용하는 Util 클래스에 static 메서드로 정의하기(공통 메서드처럼)
  • @ControllerAdvice를 사용하여 전역컨트롤러에서 정의하기

전자의 경우는 아래처럼 정의하여 각 컨트롤러에서 사용하면 된다.

public class LoginUtility {
	/**
	 * 스프링 시큐리티 접속 정보 가져오기
	 */
	public static customUser getCustomUser(){
		//스프링 시큐리티 컨텍스트로 부터 가져오기
		if(SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null){
			if(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getClass().equals(customUser.class)){
				customUser customUser = (customUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
				return customUser;
			}
		}
		return null;
	}
}

다만 필자는 모든 컨트롤러에서 사용할 수 있도록 @ControllerAdvice를 사용하며, 전역적인 데이터 처리를 위해서 @ModelAttibute를 사용하고자 했다.

로그인 정보를 가져오는 행위는 공통 메서드로 처리하기보다는 공통 모델 속성으로 구현하는게 좋다고 생각해서 이처럼 구현했다.

@ControllerAdvice란?

더보기

Spring Framework에서 컨트롤러와 관련된 전역 예외 처리, 데이터 바인딩, 모델 속성 추가 등을 용이하게 처리하기 위해 사용된다.

공통적인 로직(예: 모델 속성 추가)을 모든 컨트롤러에 적용할 수 있어 코드가 더 간결하고 유지보수가 용이해진다.

1. 스프링 시큐리티 컨텍스트로부터 로그인 정보 가져오기

@ControllerAdvice
public class baseController {
	/**
	 * 스프링 시큐리티 접속 정보 가져오기
	 */
	@ModelAttribute("CustomUser")
	protected customUser getCustomUser(){
		//스프링 시큐리티 컨텍스트로 부터 가져오기
		if(SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null){
			if(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getClass().equals(customUser.class)){
				customUser customUser = (customUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
				return customUser;
			}
		}
		return null;
	}
}

SecurityContextHolder(스프링 시큐리티 컨텍스트)는 로그인 정보를 가지고 있기때문에 여기서 로그인 정보를 추출했다.

또한 모든 컨트롤러, jsp에서 사용할 수 있도록 @ModelAttribute 사용하여 모델 속성을 추가했다.  

@ModelAttibute 애노테이션을 메서드 자체에 사용하면 메서드의 리턴값이 자동으로 모델 애트리뷰트로 추가된다.

즉 어떤 객체를 모델의 기본값으로 설정하고 싶을 때, 다시말하면 공통으로 필요한 모델 애트리뷰트가 필요할 때 유용하다.

모델 애트리뷰트의 이름은 직접 지정할 수도 있고, 모델 속성의 이름을 지정하지 않으면 Object 타입과 컨벤션에 의해 자동 명명된다.

이처럼 구현하면 CustomUser에는 로그인 정보가 담겨있어 jsp에서도 쉽게 사용할 수 있게 된다.

2. 컨트롤러에서 사용법

public class testController {

    @RequestMapping(value="/test.do" , method=RequestMethod.GET)
    public String test(@ModelAttribute("CustomUser") customUser user1, Model model) throws Exception {
        customUser user2 = (customUser) model.getAttribute("CustomUser");
    	System.out.println(user1.getUser_id()); //admin
    	System.out.println(user2.getUser_id()); //admin
        return "test";
    }
}

로그인 정보를 가져오는 2가지 방법이 있는데 model을 사용하는 것과 @ModelAttribute를 사용하는 것이다.

  • model 애트리뷰트에 이미 추가가 되어 있기 때문에 model에서 추출이 가능하다.
  • @ModelAttribute를 통해 명시적으로 가져올 수 있다.

단 이미 @ControllerAdvice에서 정의하고 있기때문에 굳이 로그인 정보를 컨트롤러에서 다시 정의할 필요가 없다.

3. jsp에서 사용법

<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<!-- sec 태그 사용 --> 
<li><p>환영합니다. <sec:authentication property="principal.user_role"/> <sec:authentication property="principal.user_name"/>님.</p></li>

<!-- @ModelAttribute 사용 --> 
<li><p>환영합니다. ${CustomUser.user_role} ${CustomUser.user_name}님.</p></li>

 

위에처럼 sec태그를 사용하거나 모델을 사용하여 jsp에 사용할 수 있다.

추가적으로 sec태그에 대해 알고 싶다면 아래 링크를 확인해보면 좋다.

https://velog.io/@nugoory20/Spring-Security-sec-%ED%83%9C%EA%B7%B8%EC%9D%98-%ED%91%9C%ED%98%84%EC%8B%9D%EB%93%A4

 

Spring Security _ sec 태그의 표현식들

principalDB와 연동된 security 로그인이 활성화되었다면 이제 jsp 파일 내부에sec 태그를 활용해볼 수 있습니다.springframework의 security tag 경로를 설정하고 sec라는 이름으로 임폴트했습니다.이제 sec를

velog.io

잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다.

 

반응형