쉽게 쉽게

[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

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

     

    반응형