모든 사용자의 세션을 확인하기 위해서는 sessionRegistry를 이용해야 하고 이를 주입받기 위해서는 SecurityConfig파일에 등록해주어야 합니다. @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } private final SessionRegistry sessionRegistry; @GetMapping("/") public String home(HttpServletRequest request, Model model, HttpSession session) { List allPrincipals = sessionRegistry.getAllPrincipals(); // 각 Principal(사용자)..
HttpServletRequest.getSession(default == true) - request.getSession(true) : 세션이 있으면 기존 세션 반환 세션이 없으면 새로운 세션을 생성해서 반환 - request.getSession(false) : 세션이 있으면 기존 세션 반환 : 세션이 없으면 null을 반환 - 기존 세션의 여부는 JSESSIONID로 구분합니다. session저장소에 JSESSIONID와 매칭되는 세션이 존재하는지! * JSESSIONID : 톰캣 컨테이너에서 세션을 유지하기 위해 발급하는 키. 로그인 구현 @Controller @RequiredArgsConstructor public class MemberController { private final MemberSe..
세션을 이용한 로그인의 동작원리 1. 인증에 성공했을 때 세션생성(SessionStore에 Map(SessionId, Session)의 형태로 관리 2. 세션에 Map("LOGIN_MEMBER", loginObject)의 형태로 저장 3. response에 sessionId가진 쿠키("JSESSION_ID", sessionId)를 담아 반환 4. 클라이언트는 자원 요청시 쿠키를 가지고 접근 5. 쿠키에 담긴 세션아이디가 서버의 저장소에 존재한다면 세션객체 반환 6. 세션에서 "LOGIN_MEMBER"에 매칭되는 loginObject 반환 -> 이렇게 반환 받은 로그인 객체를 이용하여 인증을 유지합니다. 구현 세션의 이해를 돕기위해 직접 Session을 관리하는 SessionManager클래스를 구현해 로..
세션 인증의 동작원리 세션인증은 다음과 같은 방법으로 이루어집니다. 1. 로그인요청 2. 로그인 성공 시 세션발급(사용자 정보 저장) 3. 해당 세션에 매핑되는 세션id를 쿠키에 심어 클라이언트 측에 전달 4. 자원 접근(이 세션id를 가지고 접근한다면 로그인 상태 유지) 즉 로그인 이후에는 세션을 통해 로그인 상태를 유지합니다. 따라서 이 세션id를 공유한다면 같은 사용자임을 보장받을 수 있습니다. 세션 고정 취약점( + 고정 보호) 제가 이번 포스팅에 설명할 내용은 세션고정 취약점입니다. * 세션 고정이란 로그인 시 발급받은 세션 ID값이 로그인 전 후 모두 동일하게 사용되는 것입니다. 이렇게 되면 다음과 같은 문제가 발생할 수 있습니다. 해커는 웹(Target)서버에 접근하여 정상 세션을 발급받는다..
지연 로딩(LAZY)과 즉시로딩(EAGER) @Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "member_name") private String name; @ManyToOne(fetch = FetchType.EAGER) //@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; } EAGER를 해둘 경우에는 연관관계가 걸려있는 엔티티를 모두 조회해서 실제 객체로 바인딩 됩니다.(Member만 조회해도 Team에 대한 쿼리까지 함께 나갑니다.) LAZ..
- JWT인증이 설정되어 있다면 원래대로라면 로그인을 통해 인증한 후 accessToken값을 매 요청마다 설정해주어야 합니다. - 이렇게 되면 컨트롤러 테스트에서 MockMvc를 이용해 요청을 날릴 때 마다 로그인을 먼저 한 다음 accessToken값을 얻어와서 다시 요청을 해야합니다. - 일단 결론적으로 이 과정을 WithUserDetails를 통해 생략할 수 있음을 확인했습니다. @WithUserDetails("user1") // "user1" 값은 등록된 Bean 중 UserDetailsService를 찾아 loadUserByUsername의 파라미터 값으로 바인딩된다. - WithUserDetails를 사용하면 로그인 과정이 진행되고 결과적으로 SecurityContext에 Authentica..
@preAuthorize 메서드를 실행하기 전에 권한을 검사하는 기능을 지원하는 어노테이션으로 아래 익스프레션을들을 조합하여 사용할 수 있습니다. hasRole([role]) : 현재 사용자의 권한이 파라미터의 권한과 동일한 경우 true hasAnyRole([role1,role2]) : 현재 사용자의 권한디 파라미터의 권한 중 일치하는 것이 있는 경우 true principal : 사용자를 증명하는 주요객체(User)를 직접 접근할 수 있다. authentication : SecurityContext에 있는 authentication 객체에 접근 할 수 있다. permitAll : 모든 접근 허용 denyAll : 모든 접근 비허용 isAnonymous() : 현재 사용자가 익명(비로그인)인 상태인 경..
@AllArgsConstructor 사용의 문제점 @AllArgsConstructor는 모든 필드를 가진 생성자를 만들어줍니다 @AllArgsConstructor public class BuildMe { private String name; private int age; private String keyword; } ------------------------------------------------------------------------------------- public class BuildMe { private String name; private int age; private String keyword; public BuildMe(final String name, final int age, ..
테스트를 짜던 도중 set을 이용해 데이터를 변경시에는 DB에 반영이 안되는데 Service를 이용할 시에는 반영되는 현상을 보고 Transactinal을 붙였더니 뭔가 다 안되길래 해결한 경험을 적습니다! Spring Boot Test에서는 테스트 수행 후에 트랜잭션 커밋 내역을 모두 롤백시킵니다. 어렴풋이 알고는 있었지만 평소에 테스트 할 때에 service난 repository를 주입받아서 사용하면 데이터가 저장되었던 기억과 혼동되어서 정확한 동작원리를 파악하지 못하고 있었습니다. 정확히는 테스트 레벨에 붙어있는 Transactional은 롤백 되지만 주입받아서 사용하는 Service단이나 Spring Data JPA에서 기본으로 제공하는 @Transactinal은 롤백되지 않습니다. 또한, 이 둘..
Error creating bean with name 'entityManagerFactory' defined in class path resource Could not determine recommended JdbcType for `com.sbb.question.domain.Question` entityManagerFactory를 초기화 하지 못했다 -> `com.sbb.question.domain.Question` 에 권장되는 jdbcType을 결정할 수 없다 위와 같은 에러가 발생하는 이유로 여러가지 이유가 있는 존재합니다.(Entity생성 오류로 추정) 보통 연관관계 설정을 잘못해서 발생하는 것 같은데 저는 @GeneratedValue를 auto로 놔둬서 오류가 놨던것 같습니다. -> mariaDB..