묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
스프링 시큐리티 문의 (webSecurityConfigurerAdapter 취소선)
안녕하세요. 스프링시큐리티 로그인관련 진행하다가 extends webSecurityConfigurerAdapter 가 취소선이 나와서 확인해보니 현재는 사용하지않는다고 알게되었습니다. 나름 바꾸면서 진행중인데authenticationManager() 를 사용하려면 어떻게해야되는지 알 수 있을까요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
35강 책 대출/반납 기능 리팩토링과 지연로딩 적용 후의 문제
안녕하세요 공부하는 개발자 최태현님!재미있게 강의 듣던 중 질문 드릴 부분이 있어 또 찾아오게 되었네요 ㅎㅎ이번에는 '35강 책 대출/반납 기능 리팩토링과 지연로딩' 적용 후의 문제 에 대해서 질문 남겨보겠습니다!user_loan_history의 대출 / 반납 시,대출(book_name : java / user_id : 22)반납 (book_name : java / user_id : 22)위와 같이 '처음' 한번의 '대출과 반납' 에는 문제가 없으나,아래와 같이 '이미' '대출과 반납'이 진행되었던 [id: 7 / book_name : java] 를 가지고 '대출과 반납 을 '다시' 진행해보면,,대출이 된 상태(is_return : 0)는 정상적으로 유지가 됩니다. (대출 시도 시, 이미 이미 대출된 책이라는 에러 메시지 정상 출력) 반면 반납의 경우, 브라우저 alter창에서는 반납 되었다고 뜨지만 DB에서는 정상적으로 적용되지 않네요., ㅠㅠ (브라우저통해 반납 시도 시, 무한 성공 but DB 미적용 )(위 이미지 상의 '일기'라는 책은 검증용으로 '대출과 반납'을 단 1회만 해둔 상태)추가 테스트 (history 데이터 삭제 후 진행)책 반납 시, 해당 책에 관한 데이터가 user_loan_history에서 기록이 삭제 되도록 따로 구현이 필요한 부분일까요..??(강의에 있는데 제가 놓친 부분이라면 죄송합니다..!!)그럼, 오늘 하루도 잘 마무리 하시고 행복한 밤 되시길 바라며이번에도 미리 답변 감사드리며 배포 진행하고 있을게요!행복하세요 감사합니다!
-
미해결[개념은 호옹~, 실습 빡] 스프링 부트, 입문!
21강 질문
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.@Test @Transactional void delete_성공____존재하는_id_입력() { //예시 Long id = 1L; Article expected = null; //실제 Article deleted = articleservice.delete(id); //비교 assertEquals(expected,deleted); }//이렇게 작성하여 //비교를했는데.. //결과는 Expected :null Actual :Article(id=1, title=가가가가, content=1111) //이렇습니다 articleservice.delete(id); // 이거 삭제되어서 null 이 나오는거 아닌가요ㅕ ??..
-
미해결스프링 시큐리티
기본 DaoAuthenticationProvider사용시 인증객체 조회 에러
프로젝트를 다시 만들어 실습을 진행중에 있습니다.이번 프로젝트에서는 CustomAuthenticationProvider를 생성하지 않고 기본으로 사용되는 DaoAuthenticationProvider를 사용할려고 CustomAuthenticationProvider를 등록하지 않았습니다.그런데@GetMapping("/denied") public String accessDenied(@RequestParam(value = "exception", required = false) String exception, Model model) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Account account = (Account)authentication.getPrincipal(); model.addAttribute("username", account.getUsername()); model.addAttribute("exception", exception); return "user/login/denied"; }이 컨트롤러에서 인증 객체 조회가 되지 않아 에러가 발생했습니다.기존 프로젝트의 CustomAuthenticationProvider에서의 인증 로직이 끝나고 UsernamePasswordAuthenticationToken타입으로 인증객체가 return되고 이것이 SecurityContext에 저장되는 흐름과현재 진행중 프로젝트의 DaoAuthenticationProvider에서 인증 로직이 끝나고UsernamePasswordAuthenticationToken타입으로 인증객체가 return되고 이것이 SecurityContext에 저장되는 흐름이 완전히 동일하다고 생각되어서기존 프로젝트와 똑같이 컨트롤러에서 인증객체가 조회될 것이라고 생각했는데 그렇지 않습니다.혹시 인증 흐름상에서 제가 놓치고 있는 부분이 있는건가요?
-
해결됨토비의 스프링 부트 - 이해와 원리
메소드 빈주입
안녕하세요 토비님 강의 잘듣고있습니다!다름이 아니라 강의 내용중 메서드 파라미터에 빈을 주입 받아 사용하는 것에 궁금증이 생겨 질문드립니다. 일반 적으로 빈을 주입받아 사용할 때 @Autowired나 생성자 등으로 초기화를 해주었는데, 위의 코드의 매개변수는 그런 과정이 없이 바로 빈을 주입받는 것인가요 ?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
catalog 테이블 자동 create-drop 가 안됩니다.
안녕하세요 application.yml 설정을하고 서버 시작 시 CREATE문자체가 동작을안하는것같습니다.application.yml 과 CatalogEntity.java 는 다음과같습니다. 문제가무엇일까요...
-
해결됨토비의 스프링 부트 - 이해와 원리
질문드립니다.
안녕하세여 초보적인 질문드려서 죄송합니다..Configuration ProxyBeanMethods 값을 false 를 주면 호출 할때마다 새로운 객체를 생성하게 되는데.. 다시 말해 싱글톤임을 보장 받을수 없게 되는걸로 이해하였습니다. 아마 false주는 경우는 없을듯합니다만 혹시 사례가 있을까요?'굳이' 라는 말을 강의에서 계속 하셔서 사례라고 하면 생각해봤을때 싱글톤의 단점인것을 보안하기 위해 사용되는건지? 아니면 성능적인것 때문에 그런지 궁금합니다.마지막 내용에 spring 에 실제 사용된 내용으로 봤을떈, 단순한 Configuration 일땐 false를 주면 될듯한데. 디테일한 사례가 궁금합니다. 감사합니다.
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
ConstraintMode.NO_CONSTRAINT 역할
3분 43초에 외래키가 되면 null이 될 수 없다고 하셨습니다.근데, 제가 알기론 외래키는 null을 허용합니다... 혹시, jpa에서는 기본적으로 외래키에 null을 허용하지 않는걸까요?
-
미해결스프링 시큐리티 OAuth2
Resource Owner Password grant 방식 문의
안녕하세요.oauth 를 사용하여 마이크로서비스 인증/인가를 구현하는 경우가 꽤 많은 것으로 알고 있습니다.구글링을 해보면 사용자가 최초 로그인 시, 인증서버에서 jwt 토큰을 발행해주고 사용자는 jwt 토큰을 사용하여 각 마이크로서비스의 api 를 요청하는 컨셉으로 확인됩니다.이때 각각의 마이크로서비스는 oauth 에서 리소스 서버의 역할로 볼 수 있고요.그래서 최초 토큰을 발행하는 인증 방식은 단순히 id/password 를 넘겨서 토큰을 발행받는 Resource Owner Password grant 방식을 사용했던 것 같은데요.하지만 강의에서 설명해 주신대로 최근 스프링 시큐리티의 Authorization 서버에서는 Resoure Owner Password grant 방식을 더 이상 사용할 수 없다고 하셨어요.그렇다면 마이크로서비스를 위해 Authorization 서버를 구현할 때, 토큰 발행을 어떤 방식으로 구현하는 것이 바람직할까요? 제3의 앱에서 로그인을 하는 것도 아닌데 Authorization code 방식을 적용할 필요가 있는 것인지 모르겠네요.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
질문 드립니다
안녕하세요 선생님.JdbcTemplate이 있기 때문에 UserController가 인스턴스화되지 않아도 실행된다고 하셨는데 CalculatorController에 JdbcTemplate이 없는데 어떻게 실행되는 건가요?답변 감사드립니다.
-
해결됨스프링 시큐리티
provider등록시에 우선권이 궁금합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.좋은 강의 감사합니다. 공부중에 궁금한게 있어서 글을 적습니다. CustomAuthenticationProvider는 현재 support로 UsernamePasswordToken인지 확인하고 있는데 DaoProvider의 경우에도 같은UsernamePasswordToken으로 검증하고 있던데 이런 경우 제가 등록한 provider가 더 우선권을 갖게 되어서 provider list를 순회 할때 custom provider가 더 먼저 지나가게 됨으로 daoprovider는 거치지 않는 것이 맞는건가요?또한 제가 등록한 custom provider는 parent로 daoprovider를 갖게 되는지도 궁금합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
[9:00] fail(); 에서 에러가 발생합니다.
아래와 같은 에러가 발생합니다.확인 한번만 부탁드립니다.(코드 추가했습니다.)
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
컨트롤러를 인식 못하는거같습니다. 404에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]여기에 질문 내용을 남겨주세요.컨트롤러를 인식하지 못하는거같습니다 무슨 문제가있는지 궁금합니다
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
veiw spring! 가 안되요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
해결됨스프링 부트 - 핵심 원리와 활용
Tomcat에 대해 질문드립니다.
안녕하세요. 강의를 보고 궁금한 점이 생겨 질문드립니다.Java 진영에서 말하는 WAS의 정의를 보면'웹 애플리케이션 서버는 대부분이 자바 기반으로 주로 자바 EE 표준을 수용하고 있으나, 자바 기반이지만 자바 EE 표준을 따르지 않는 제품과 .NET이나 Citrix 기반인 비 자바 계열도 존재한다' 라고 설명되어있습니다.Tomcat은 아파치 재단에서 만든 웹 컨테이너(서블릿 컨테이너)만 있는 WAS라고 설명하는데웹 컨테이너만 지원하는 Tomcat을 WAS라고 할 수 있는건지 궁금합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
requests.parm 이 오류나요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]controller 에서 만들었는데이렇게 오류나는데 어떻게 해야되나요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Controller를 인식하지 못하는것같습니다
새로운 프로젝트를 만들었는데 Controller를 인식하지 못해서 그런지 404 error만 나옵니다ㅜㅜ.SpringBootApplication의 하위 폴더에 Controller를 만들었고@Controller 어노테이션도 붙여줬는데인식하지 못해서 가장 기본적인 "hello"를 못찍고 있습니다ㅜㅜ. 너무 기본적인 질문인데 해결하지 못해서 올리게되었습니다.
-
미해결스프링 배치
spring batch 트랜잭션 질문입니다.
아래 설명해주신것처럼 스프링배치에서 외부에서 @Transactional 을 쓰는것을 허용하지 않는다는것을 확인했습니다.https://brunch.co.kr/@anonymdevoo/50여기를보고 semaphore.acquire를 하고 외부 트랜잭션이 끝나지 않아서 afterCompletion에서 해당 semaphore.release를 호출하지 못한다는것을 확인하였습니다.하지만 아래처럼@RequiredArgsConstructor @Configuration public class TaskletStepConfiguration { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; @Bean public Job batchJob() { return this.jobBuilderFactory.get("batchJob") .incrementer(new RunIdIncrementer()) .start(taskStep()) .next(chunkStep()) .build(); } @Bean @Transactional public Step taskStep() { return stepBuilderFactory.get("taskStep") .tasklet((contribution, chunkContext) -> { System.out.println("step1 has executed"); return RepeatStatus.FINISHED; }) .build(); } @Bean @Transactional public Step chunkStep() { return stepBuilderFactory.get("chunkStep") .<String, String>chunk(3) .reader(new ListItemReader(Arrays.asList("item1","item2","item3"))) .processor(new ItemProcessor<String, String>() { @Override public String process(String item) throws Exception { return item.toUpperCase(); } }) .writer(list -> { list.forEach(item -> System.out.println(item)); }) .build(); } } @Transactional을 걸어도 잘 동작하는데 제가 놓친 부분이있을까요?디버깅을 거며 확인했는데도 잘 모르겠습니다..브랜치는 4.2.4.1입니다.
-
미해결스프링 부트 - 핵심 원리와 활용
강의 PPT 자료 관련 문의
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요! 강의 잘 듣고 있습니다.다름이 아니라 올려주신 수업 자료에는 '스프링 부트 소개' 파트에서 사용하신 PPT 자료가 업로드 되어 있지 않습니다.복습을 위해 해당 자료가 있으면 좋을듯 한데, 추후 따로 업로드 해주실 수 있는지 궁금합니다.감사합니다!
-
해결됨스프링 시큐리티 OAuth2
Ajax 인증시 인가코드가 발급 되지 않는 원인 문의
Spring Authorization 1.0,1 기반으로 개발을 하고 있습니다. 인가코드를 발급 할떄 FormLogin 기본 설정을 사용하면 인가코드가 발급이 되는데 Ajax 로 로그인을 하면 인가코드가 발급되지 않고 있습니다. 디버깅을 해보면 로그인인 후 OAuth2AuthorizationEndpointFilter 는 실행되는데 @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (!this.authorizationEndpointMatcher.matches(request)) { filterChain.doFilter(request, response); return; } try { Authentication authentication = this.authenticationConverter.convert(request); if (authentication instanceof AbstractAuthenticationToken) { ((AbstractAuthenticationToken) authentication) .setDetails(this.authenticationDetailsSource.buildDetails(request)); } Authentication authenticationResult = this.authenticationManager.authenticate(authentication); if (!authenticationResult.isAuthenticated()) { // If the Principal (Resource Owner) is not authenticated then // pass through the chain with the expectation that the authentication process // will commence via AuthenticationEntryPoint filterChain.doFilter(request, response); return; } if (authenticationResult instanceof OAuth2AuthorizationConsentAuthenticationToken) { if (this.logger.isTraceEnabled()) { this.logger.trace("Authorization consent is required"); } sendAuthorizationConsent(request, response, (OAuth2AuthorizationCodeRequestAuthenticationToken) authentication, (OAuth2AuthorizationConsentAuthenticationToken) authenticationResult); return; } this.authenticationSuccessHandler.onAuthenticationSuccess( request, response, authenticationResult); } catch (OAuth2AuthenticationException ex) { if (this.logger.isTraceEnabled()) { this.logger.trace(LogMessage.format("Authorization request failed: %s", ex.getError()), ex); } this.authenticationFailureHandler.onAuthenticationFailure(request, response, ex); } } FormLogin 적용시에는 authenticationResult의 principal 에 UsernamePasswordAuthenticationToken이 설정되어 인가 코드가 정상적으로 발급되는데 AjaxLogin 적용시에는 authenticationResult의 principal 에 AnonymousAuthenticationToken이 설정되어 인가 코드가 정상적으로 발급되지 않고 403 예외가 발생합니다.AuthenticationProvider 구현체에서는 정상적으로 토큰을 저장하고 있습니다. AuthenticationProvider 구현체 소스@Component @RequiredArgsConstructor public class CustomAuthenticationProvider implements AuthenticationProvider { private final CustomUserDetailsService customUserDetailsService; private final PasswordEncoder passwordEncoder; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { if(authentication == null){ throw new InternalAuthenticationServiceException("Authentication is null"); } LoginRequestDto loginRequestDto = (LoginRequestDto)authentication.getPrincipal(); String password = loginRequestDto.getLoginPassword(); UserAdapter userAdapter = (UserAdapter) customUserDetailsService.loadUserByLoinRequestDto(loginRequestDto); if (!passwordEncoder.matches(password, userAdapter.getCurrentUser().getLoginPwd())) { throw new BadCredentialsException("BadCredentialsException"); } CustomAuthenticationToken result = CustomAuthenticationToken.authenticated(userAdapter.getCurrentUser(), authentication.getCredentials(), userAdapter.getAuthorities()); result.setDetails(authentication.getDetails()); return result; } @Override public boolean supports(Class<?> authentication) { return CustomAuthenticationToken.class.isAssignableFrom(authentication); } } 이외 Custom 소스Spring Security 설정@EnableWebSecurity @RequiredArgsConstructor @Configuration public class DefaultSecurityConfig { private final CustomAuthenticationProvider customAuthenticationProvider; // private final CustomUserDetailsService customUserDetailsService; @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public CustomAuthenticationProcessingFilter customAuthenticationProcessingFilter() throws Exception { CustomAuthenticationProcessingFilter filter = new CustomAuthenticationProcessingFilter(); // filter.setAuthenticationManager(authenticationManager(null)); filter.setAuthenticationManager(new ProviderManager(customAuthenticationProvider)); // filter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler()); // filter.setAuthenticationFailureHandler(customAuthenticationFailureHandler()); return filter; } // @formatter:off @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorizeRequests ->authorizeRequests .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() .requestMatchers(new AntPathRequestMatcher("/")).permitAll() .requestMatchers(new AntPathRequestMatcher("/login/**")).permitAll() .requestMatchers("/api/login/**").permitAll() .requestMatchers("/api/registered-client/**").permitAll() .anyRequest().authenticated() ); http.addFilterBefore(customAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class); http.exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer .authenticationEntryPoint(new CustomLoginAuthenticationEntryPoint()) .accessDeniedHandler(customAccessDeniedHandler()) ); // http.userDetailsService(customUserDetailsService); // http.formLogin(); http.csrf().disable(); return http.build(); } // @formatter:on @Bean public AccessDeniedHandler customAccessDeniedHandler() { return new CustomAccessDeniedHandler(); } @Bean public AuthenticationSuccessHandler customAuthenticationSuccessHandler() { return new CustomAuthenticationSuccessHandler(); } @Bean public AuthenticationFailureHandler customAuthenticationFailureHandler() { return new CustomAuthenticationFailureHandler(); } } Ajax 로그인 처리 필터 소스public class CustomAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { private final ObjectMapper objectMapper = new ObjectMapper(); private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/login", HttpMethod.POST.name()); public CustomAuthenticationProcessingFilter() { super(DEFAULT_ANT_PATH_REQUEST_MATCHER); } public CustomAuthenticationProcessingFilter(AuthenticationManager authenticationManager) { super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } LoginRequestDto loginRequestDto = objectMapper.readValue(request.getReader(), LoginRequestDto.class); if(StringUtils.isEmpty(loginRequestDto.getLoginId())||StringUtils.isEmpty(loginRequestDto.getLoginPassword())) { throw new IllegalStateException("Username or Password is empty"); } CustomAuthenticationToken authRequest = CustomAuthenticationToken.unauthenticated(loginRequestDto, loginRequestDto.getLoginPassword()); authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); return getAuthenticationManager().authenticate(authRequest); } } CustomAuthenticationToken 소스public class CustomAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; private final Object principal; private Object credentials; public CustomAuthenticationToken(Object principal, Object credentials) { super(null); this.principal = principal; this.credentials = credentials; setAuthenticated(false); } public CustomAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) { super(authorities); this.principal = principal; this.credentials = credentials; super.setAuthenticated(true); // must use super, as we override } public static CustomAuthenticationToken unauthenticated(Object principal, Object credentials) { return new CustomAuthenticationToken(principal, credentials); } public static CustomAuthenticationToken authenticated(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) { return new CustomAuthenticationToken(principal, credentials, authorities); } @Override public Object getCredentials() { return this.credentials; } @Override public Object getPrincipal() { return this.principal; } }