• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

HttpSecurity.anonymous 메소드 질문

20.10.01 21:45 작성 조회수 653

0

안녕하세요.

강의를 학습 후 추가적으로 spring docs를 보면서 공부하고 있는데요. anonymous 메소드 설명을 읽고 익명 사용자를 서비스 내에서 어떻게 표현할지 설정하는 방법이라고 이해했습니다.

그래서 간단한 실험을 위해 http.anonymous().authorities("ROLE_USER"); 이런식으로 설정하면 인증을 하지 않아도 contextholer에 principal 객체가 담기기를 희망했습니다.

@Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().authorities("ROLE_USER");
http.authorizeRequests()
.mvcMatchers("/", "/info", "/account/**", "/signup").permitAll()
.mvcMatchers("/admin").hasRole("ADMIN")
.mvcMatchers("/user").hasRole("USER")
.anyRequest().authenticated()
.accessDecisionManager(accessDecisionManager());
http.formLogin();
http.httpBasic();

http.logout().logoutSuccessUrl("/");

SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}

하지만, AnonymousAuthenticationFilter가 인증 객체를 담아줄 것이라는 예상과 달리 principal 객체는 담겨있지 않더군요 ㅜㅜ.  해당 메소드는 어떻게 사용하는 걸까요?

답변 4

·

답변을 작성해보세요.

2

네 문서와 코드로 확인한 내용이 맞습니다. 익명으로 인증된 경우에 분명히 "anonymouse"라는 principal이 존재하긴하지만 요청 매개변수에 null이 들어옵니다. 익명인증 객체는 인증된 사용자가 없는거나 마찬가지로 취급하기 때문에 null로 처리하는게 타당하다 결정한 것 같습니다. 저도 그게 자연스럽다고 생각합니다. 오히려 anonymous인데 Principal이 null이 아니면 이건 진짜로 인증된 사용자인지 아닌지 다시 확인할 방법이 필요해 지겠죠. null체크가 아니라.

1

principal 객체가 담겨있지 않은지 어떻게 확인해보셨는지요? 익명 필터는 문서에 적혀있는대로 Authenicaion이 없는 겨웅에 anonymousUser라는 문자열로 principal을 만들어 줍니다. 지금 하신 설정은 그 principal이 가지고 있을 기본 권한을 설정하신거구요.

0

답변 감사합니다.

0

답변 감사합니다. 맞아요. 질문할 때, Authorities와 principal이 같은 역할을 하는지 알았는데 공부하면서 권한과 이름으로 차이가 있다는 것을 알게 되었습니다. 더 공부해서 어느 정도 스스로 답을 찾기는 했습니다. 혹시 제가 이해한게 맞는지 한번 확인해주시면 감사하겠습니다.

제가 원하는 상황은 아래 처럼 Principal 객체를 메소드 파라미터로 설정했을 때, document에 있는 것처럼 해당 객체가 anoymousUser를 담고있는 상황을 기대했는데 null 객체가 담겨있더라고요. 

@GetMapping("/user")
public String user(Model model, Principal principal) { // principal 객체 null
model.addAttribute("message", "Hello Admin, " + principal.getName());
return "user";
}

@GetMapping("/async-handler")
@ResponseBody
public Callable<String> asyncHandler() {
SecurityLogger.log("MVC");
return () -> {
SecurityLogger.log("Callable");
return "Async Handler";
};
}

stackoverflow와 document를 읽어보니 궁금증을 해결할 수 있었습니다.SecurityContextHolder.getContext().getAuthentication() 메소드를 통해서는 인증없이 Authentication객체에 잘 접근할 수 있었지만 Servlet API(Controller 메소드)를 통해 호출한 API는 동작을 하지 않는것 같드라고요. 

// Authentication 객체 확인 가능
public static void
log(String message) {
System.out.println(message);
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // anonymousUser
System.out.println("Thread: " + Thread.currentThread().getName());
System.out.println("Principal: " + principal);
}

이 질문은 spring security 강의에 하는게 맞는것 같은데 해당 강의에서는 아직(제가 수강한 진도 기준) anonymous 내용을 다루지 않는것 같아서 여기에 질문하게 되었네요...

reference

https://stackoverflow.com/questions/51395906/understanding-the-difference-of-permitall-and-anonymous-in-spring-security
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#anonymous

(10.14.1 Overview 두번째 문단)

 Calls to servlet API calls such as getCallerPrincipal, for example, will still return null even though there is actually an anonymous authentication object in the SecurityContextHolder.