스프링 시큐리티 6를 수업때 배우기 전
독학을 하며 겪은 여러 에러를 정리하는 포스트입니다.
매우 기초적인 에러들도 있었지만 독학으로 하나씩 해결했던 과정을 남깁니다.
1. spring security6 로그인 페이지 커스터마이징 작업 중 테스트 후 무한 리디렉션 발생
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) -> csrf.disable())
.authorizeHttpRequests((authorizeRequest) ->
authorizeRequest
.requestMatchers("/", "sports").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated())
.formLogin((login) ->
login
.loginPage("/login").loginProcessingUrl("/login_post").defaultSuccessUrl("/"));
return http.build();
}
}
로그인 페이지에는 permitAll()을 안해줘서 계속 로그인 페이지를 리디렉션해서 문제발생
2. 시큐리티 6 적용후 정적자원들 CSS, JS, 이미지 등이 로드가 안됨
SpringBoot에서 SpringSecurity를 적용하면 Security Filter에 걸려 css가 적용되지 않아서 따로 설정을 통해 static 파일을 설정필요.
여러 방법 시도 중 대부분의 포스팅들이 .antMatchers() 메서드를 사용해 경로를 지정해줬는데,
antMatchers()가 spring security 6 버전부터 삭제되어 미지원
공식문서를 찾아보고 .requestMathers()로 대체
@Bean
protected WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers("/static/**","/css/**", "/js/**","/img/**", "/fonts/**", "/slick/**");
}
3. 시큐리티 중 회원가입기능 구현 중 입력받은 DTO의 password가 Entity로 컨버트 할때 null이되는 현상
엔티티인 Member.class 에는 @Setter가 아닌 빌더로 하는 방식이 맞다고 수업때 들어 세터를 빼고 한것이 ModelMapping과정에서 에러가 난것
4. 랜딩 페이지가 permitAll()인데도 계속 비로그인 상태 시 로그인 페이지로 넘어가는 현상 발생
@GetMapping("/")
public String main(Model model) {
// 추천 시설
Map<String, Object> recmdspcaeList = new HashMap<String, Object>();
recmdspcaeList = spaceService.recommendSpaceList();
recmdspcaeList.get("data");
model.addAttribute("data", recmdspcaeList.get("data"));
// 로그인 정보
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Member entity = (Member) memberService.loadUserByUsername(authentication.getName());
MemberDto member = memberConverter.convertToDto(entity);
model.addAttribute("member", entity);
return "index";
}
로그인 유저의 이름을 메인페이지에 출력하려고 로그인 정보를 가져오려고했던것때문에 계속 로그인요청 발생 비로그인상태기 떄문에 세션에 로그인정보 없음
// 로그인 정보
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()
&& !(authentication instanceof AnonymousAuthenticationToken)) {
MemberPrincipalDetails principal
= (MemberPrincipalDetails) memberService.loadUserByUsername(authentication.getName());
MemberDto memberDto = principal.toMemberDto();
model.addAttribute("member", memberDto);
}
⇒ 비로그인 상태일때의 AnonymousAuthenticationToken 타입이 아닐때를 조건에 넣어 부분적으로 로그인 정보를 가져오게하고, 커스텀 UserDetails구현체로 효율적인 Dto 형태로 변환하여 데이터를 뷰에 출력하는 것으로 리팩토링
++)
추후 session개념으로 스프링 시큐리티 로그인 정보를 관리하는것을 알고
로그인 로직에서 저장한 데이터를 그냥 인증형태로 불러오면 되는것으로 간편한 형태로 리팩토링
또한 이때문에 로그인을 한번했는데
중복으로 요청이 3번씩 되는 현상 발생했었음 불필요하게 요청을 여러번하는것도 위처럼 리팩토링으로 해결
** 5. 세션에 저장한 security의 로그인 데이터를 모든 컨트롤러의 모든 핸들러 메서드마다 적용하는 것은 비효율적이고 다른 방법이 있을것이라 생각함
첫번 째로는 @AuthenticationPricipal 어노테이션으로 코드를 줄였지만 이 또한 모든 핸들러 메서드마다 적용하는 것이므로 다른 방법을 찾아나섬
최종적으로 찾은 방식은 컨트롤러 클래스에 @ControllerAdvice(annotations = Controller.class)를 넣고 아래 메서드로 전체 모델 어트리뷰트를 통합하여 인수로 넣어주는 방식.
**매우 효율적이지만, 명시적인 면에서는 단점이 될 수 있으므로 명심해야할 것
6. -parameter 에러발생
- Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.
- Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.] with root cause
원인: https://hianna.tistory.com/833
[Spring Boot / 에러] Name for argument of type [java.lang.String] not specified, and parameter name information not found in c
Spring Boot 웹 프로젝트 실행 도중 아래와 같은 에러가 발생하였다. java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not found in class file either. at org.spr
hianna.tistory.com
7. 시큐리티 필터체인 구현 이후 관리자만 로그인/ 회원가입이 안되는 에러발생
1차
관리자 로그인폼과 회원가입폼을 /join/admin, /login/admin 으로 각각 설정했는데 이 또한 스프링 시큐리티의 경로 규칙상 /admin/**에 해당돼서 관리자 권한을 요청하는 걸까봐 포스트요청시 요청 URI에서 /admin을 /manage 수정
해결안됨
db에서 role만 바꾸니 일반 로그인창에서 로그인하고 관리자페이지들 접근 잘 됨
관리자가입,로그인 페이지의 문제인듯하다
Spring Boot - Request method 'POST' not supported 에러
관련에러 포스트 : https://chamch-dev.tistory.com/30
Spring Boot - Request method 'POST' not supported 에러
문제 Spring Security 설정한 Spring Boot 환경과 React 서버사이드 환경 연동 중 관련 에러가 발생하였습니다. 분석 Sprign Security는 기본적으로 CSRF에 대한 설정이 필요하므로 일어난 문제입니다. 참고 - CS
chamch-dev.tistory.com
8. 스프링 시큐리티 구현 중 관리자와 일반회원이 로그인 했을 때,
컨트롤러에서 여러 처리를 해봐도 같은 사용자 랜딩 페이지로만 가는 문제 발생
원인은 시큐리티 체인 .formLogin의 .defaultSuccessUrl이 “/”로 지정되어있었기 때문
먼저 SuccessHandler를 AuthenticationSuccessHandler를 상속받아 커스텀으로 구현하고
폼로그인에서
.successHandler(loginSuccessHandler)) 사용, 해당 권한에 맞게 잘감.
또한 시큐리티의 authorities 권한은 arrayList형태기 때문에 아래처럼 단건 조회가 아닌
if ("ROLE_USER".equals(authentication.getAuthorities())) {
response.sendRedirect("/");
}else {
response.sendRedirect("/admin/qna");
}
스트림으로 리스트 전체를 순회하여 확인해야 구현이 가능했음
'유레카' 카테고리의 다른 글
날짜 형태의 데이터를 활용할 때 (Date , Timestamp / TO_CHAR() / split()) (0) | 2024.07.25 |
---|---|
ajax 학습 메모 (0) | 2024.07.17 |
[SPA 미니 프로젝트 中] antd Menu에 링크 연결하기(5.0 버전 이슈) (1) | 2023.10.29 |