제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

ISSUE

CasAuthenticationProvider에 userDetailsChecker 멤버가 final로 선언되어 있으며, setter가 없어, 변경이 불가능함.

CasAuthenticationProvider의 역할

  • CasAuthenticationProvider(CAS)는 Spring Security에서 CAS (Central Authentication Service) 인증을 처리하는 데 사용되는 클래스로, CAS는 싱글 사인온(SSO)을 구현하기 위한 프로토콜 및 시스템.
  • CAS 서버로부터 인증 티켓을 검증하고, 사용자 세부 정보를 로드하며, 인증 토큰을 생성.
  • Spring Security 애플리케이션에서 중앙 집중식 인증을 지원. Spring Boot 앱은 인증을 위해 CAS를 사용

해결

코드

// CasAuthenticationProvider.java
public class CasAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {
	// ... other
	private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();

	/**
	 * Sets the UserDetailsChecker to be used for checking the status of retrieved user
	 * details. This allows customization of the UserDetailsChecker implementation.
	 * @param userDetailsChecker the UserDetailsChecker to be set
	 * @since 6.4
	 */
	public void setUserDetailsChecker(final UserDetailsChecker userDetailsChecker) {
		Assert.notNull(userDetailsChecker, "userDetailsChecker cannot be null");
		this.userDetailsChecker = userDetailsChecker;
	}
}

// TEST CODE

@Test
public void testSetUserDetailsChecker() throws AuthenticationException {
    CasAuthenticationProvider cap = new CasAuthenticationProvider();
    cap.setAuthenticationUserDetailsService(new MockAuthoritiesPopulator());
    cap.setKey("qwerty");
    cap.setTicketValidator(new MockTicketValidator(true));
    cap.setServiceProperties(makeServiceProperties());
    cap.afterPropertiesSet();
    CasServiceTicketAuthenticationToken token = CasServiceTicketAuthenticationToken.stateful("ST-123");

    AtomicInteger checkCount = new AtomicInteger(0);
    UserDetailsChecker userDetailsChecker = new UserDetailsChecker() {
        @Override
        public void check(UserDetails user) {
            checkCount.incrementAndGet();
        }
    };
    cap.setUserDetailsChecker(userDetailsChecker);
    cap.authenticate(token);

    assertThat(checkCount.get()).isEqualTo(1);
}
  • CasAuthenticationProvider 클래스에 setUserDetailsChecker 메서드가 추가.
  • 이 메서드는 UserDetailsChecker를 설정하고, null 값을 허용하지 않음.
  • test code
    • 다른 테스트 코드에서 사용하고 있는 CasServiceTicketAuthenticationToken을 사용하여 test
    • AtomicInteger를 사용하여 check 메서드 호출 횟수를 추적.
      • authenticatie 메소드 내부에서 check 함수를 호출
    • UserDetailsChecker의 익명 클래스를 생성하여 check 메서드가 호출될 때마다 checkCount를 증가.
    • setUserDetailsChecker 메서드를 통해 커스텀 UserDetailsCheckerCasAuthenticationProvider에 설정.

느낀점

  • 인제님이 알려주신 내용인데, 해당 클래스는 getter가 모두 없었음.
    • 오픈소스에서는 getter를 열어 둘 경우, user가 접근이 가능.
    • 노출하면 getter를 다시 뺄 수 있기에, getter를 열어두지 않는 경우 있음.
  • test 코드를 만드는 것이 조금 까다로웠는데, 다른 사람들이 만든 test code를 참고하고, 구현되어 있는 클래스들을 사용하면 어렵지 않게 test 코드를 만들 수 있었음을 깨달았음.
  • 이처럼 누구나 손쉽게 해결 가능한 issue들이 있기에 오픈소스의 issue들에 조금 더 관심을 가져야겠다 생각이 들었음.

 

+ Recent posts