아이퐁퐁
248
2021-11-25 21:47:40 작성 2021-11-25 21:50:43 수정됨
9
143

스프링 시큐리티 유저 정보 가져오는 방법 질문드립니다.


안녕하세요.


제가 게시판 만드는 공부를 하고 있습니다. 

이번에 스프링 시큐리티를 적용해서 로그인 구현을 했습니다.

그런데 이전에는 제가 작성자가 아이디가 아닌 닉네임으로 나오게 했는데

시큐리티를 적용하고 나서는 아래 코드가 먹지를 않더라구요. 

	@RequestMapping(value = "/diary/write", method = RequestMethod.POST)
	public String write(BoardVO boardVO, UserVO userVO, HttpSession session) throws Exception {

		userVO = (UserVO) session.getAttribute("user");
		String usernick = userVO.getUserNick();
		boardVO.setUserNick(usernick);
		
		boardservice.write(boardVO);
			
		return "redirect:/diary/diaryPageSearch?num=1";
	}


그래서 구글링을 해보니 유저 아이디를 가져오는 방법은 있는데

유저 아이디와 패스워드를 제외한 값을 받아오는 방법을 제 구글링 실력으로는 찾기가 어렵네요 ㅠㅠ

혹시 어떤 식으로 접근해야 유저 닉네임을 가져와서 사용할 수 있을까요? 

0
  • 답변 9

  • ROJAEKA
    160
    2021-11-25 22:30:17

    SpringSecurityContextHolder에 대해서 알아보세용

  • ROJAEKA
    160
    2021-11-25 22:32:29

    윗 내용 알아보시구.


    https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/


    여기 문서에

    @CurrentUser 검색해서 보시면, 개발할때 도움이 되실 것 같습니다.

  • 아이퐁퐁
    248
    2021-11-26 19:15:56

    ROJAEKA 님 답변 감사합니다!!

    말씀해주신 SpringSecurityContextHolder 검색해보니


    CustomUserDetails userVO = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();

    String userNick = userVO.getUserNick();


    위와 같은 형식으로 진행하는 것을 찾아서 해봤습니다만... 

    java.lang.ClassCastException: class org.springframework.security.web.authentication.WebAuthenticationDetails cannot be cast to class com.yoohyun.diary.vo.CustomUserDetails (org.springframework.security.web.authentication.WebAuthenticationDetails and com.yoohyun.diary.vo.CustomUserDetails are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @5ef6ae06)

    이란 오류가 발생하네요. 뭔가 캐스팅을 하지 못하다는 의미인 건 알겠는데 이게 정확하게 뭘 말하는지 이해가 힘드네요... 혹시 뭔가 잘못됐는지 알 수 있을까요?

  • ROJAEKA
    160
    2021-11-29 16:15:05

    클래스 형식 확인해보세요.

    SecurityContextHolder.getContext().getAuthentication().getDetails();

    를 그냥 출력해보세면, 클래스 형식을 알 수 있을 거예요.


    아마 AccountService (그러니까 로그인 서비스의) 인증에서 loadUserByUsername, 메소드가

    리턴하는 클래스의 형식이랑 달라서 생기는 오류 일 거 같네요.


    https://csy7792.tistory.com/177

    https://dncjf64.tistory.com/330

    위 글 참고해보세용.

  • ROJAEKA
    160
    2021-11-29 16:26:45 작성 2021-11-29 16:33:29 수정됨

    Principal 객체

    public class UserAccount extends User {
    
    	private static final long serialVersionUID = 1L;
    	private final TbUser account;
    
        public UserAccount(TbUser tbuser) {
    
            super(tbuser.getId(), tbuser.getPwd(), Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + tbuser.getAdminGpNo())));
    
            this.account = tbuser;
        }
    
        public TbUser getAccount() {
            return account;
        }
    
    
    
    
    
    }



    AccountService 로그인 부분


    
    @Service
    @Slf4j
    @Transactional(readOnly = true)
    @RequiredArgsConstructor
    public class AccountService implements UserDetailsService {
    
    	// Injection
    	private final tbUserRepository tbUserRepository;
    	
    	/// ...
    
        @Override
        public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException {
            Optional<TbUser> account = tbUserRepository.findById(id);
            if (account.isPresent()) {
                log.info(account.get().getName() + "님이 로그인을 시도합니다.");
                return new UserAccount(account.get());
            } else {
                ...
            }
        }


    @CurrentUser

    // Principal 객체에 담겨 있는 UserAccount의 account를 반환합니다.
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : account")
    public @interface CurrentUser {
    
    }


    @CurrentUser 사용

    @Controller
    public class LoginOutController {
    
        @Autowired
        private AccountService accountService;
    
        /*
         * 로그인 페이지
         */
        @GetMapping(value = "/login")
        public String loginForm(@CurrentUser TbUser user) {
    
        }
    
    }
    
    


  • ROJAEKA
    160
    2021-11-29 16:26:57

    제가 사용하는 방식인데, 참고하세용

  • 아이퐁퐁
    248
    2021-11-29 18:56:48

    ROJAEKA 님 정말 너무 감사합니다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

    며칠을 공부도 해보고 찾아도 봤는데 도저히 제 스스로 해결하기가 어려웠는데 

    링크 걸어주신 것들 확인하면서 테스트 해보니 해결할 수 있었습니다 정말 정말 다시 한 번 더 감사의 인사를 드립니다 감사합니다!!!!!

  • ROJAEKA
    160
    2021-11-29 21:22:22

    아고 3일 지나서, 해결했을거라고 생각했는데

    좀 걸리셨군요. 헤맨 시간도 좋은 학습이 되었을거라고 생각합니다.

    (저는 학생 때, 인프런 백기선님 스프링 시큐리티 강의를 들었는데, 많은 도움이 되었던 기억이 있네요 ㅎㅎ)


    열공하세용~


  • 아이퐁퐁
    248
    2021-11-30 19:38:42

    ROJAEKA 님 다시 한 번 감사드립니다!!

    더 열심히 노력해보겠습니다!!

  • 로그인을 하시면 답변을 등록할 수 있습니다.