Spring Security - 정수원 3일차
18314 단어 spring securityspring security
8. 인증 API - AnonymousAuthenticationFilter
- 익명사용자 인증 처리 필터
- 익명사용자와 인증 사용자를 구분해서 처리하기 위한 용도로 사용
- 화면에서 인증 여부를 구현할때
isAnnonymous()
와isAuthenticated()
로 구분하여 사용 - 인증객체를 세션에 저장하지 않는다.
9. 인증 API - 동시 세션 제어 / 세션고정보호 / 세션 정책
동시세션
- 최대 세션 허용 개수를 설정한다. ( 만약 1이라면 )
- 두 명 이상의 유저가 로그인 한다
- 두가지 경우가 있다.
- 이전 사용자 세션을 만료 하는 경우
- 현재 사용자 인증을 실패하게 하는 경우
http
.sessionManagement() // 세션관리 기능 동작
.maximumSessions(1) // 최대 허용 가능 세션 수, -1 : 무제한
.maxSessionsPreventsLogin(true); // 동시 로그인 차단(현재 세션 만료)
// false : 기존 세션만료
.invalidSessionUrl("/invalid") // 세션이 유효하지않을때 이동 할 페이지
.expiredUrl("/expired"); // 세션이 만료될 경우 이동 할 페이지
세션고정보호
http
.sessionManagement()
.sessionFixation().changeSessionId() //기본값, 세션에 id를 새롭게 변경
.sessionFixation().migrateSession() // 기존에 session에 있던 정보를 새로운 session에
// copy하여 새롭게 만들어서 사용한다.
.sessionFixation().newSession() // 이전에 Session 값을 copy하지 않고 정말 새롭게
// session을 만들어서 사용 한다.
.sessionFixation().none() // 아무런 작업도 하지않음.
세션 정책
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.Always) // 스프링 시큐리티가 항상 세션 생성
.sessionCreationPolicy(SessionCreationPolicy.If_Required) // 필요시 생성(기본값)
.sessionCreationPolicy(SessionCreationPolicy.Never) // 생성하지 않지만 이미 존재하면 사용
.sessionCreationPolicy(SessionCreationPolicy.Stateless) //생성x, 존재 x
11. 인증 API - SessionManagementFilter, ConcurrentSessionFilter
-
SessionManagementFilter 먼저 이전 사용자 세션 만료 정책을 설정한 후
session.expireNow()
정책에 따라 -
ConcurrentSessionFilter는 매 요청마다 세션이 만료되었는지 확인한다. 확인후 로그아웃 그리고 오류페이지
session.isExpired() == true
- 로그아웃처리
- 즉시 오류 페이지 응답
-
이미 이전 사용자가 있으면 SessionManagementFilter 가 expiredNow()를 해서 이전 사용자 세션을 만료 시킨다.
-
이전 사용자가 요청을 시도하면 ConcurrentSessionFilter 가 session.isExpired() 가 동작하여 로그아웃 시킴
12. 인가 API - 권한 설정 및 표현식
- 선언적 방식
- URL
http.antMatchers(”/user/**”).hasRole(”USER”)
- Method
@PreAuthorize(”hasRole(’USER’)”)
- public void user(){ System.out.println(”user”) }
- URL
- 동적 방식
- URL
- Method
선언적 URL 방식
.antMatcher("/shop/**") // url에 접근시 인증 없으면 모든페이지 인증
.authorizeRequests()
.antMatchers("/shop/login","/shop/user/**").permitAll() //이 페이지 모든 접속 가능
.antMatchers("/shop/mypage").hasRole("USER") // 페이지 유저만 가능
.antMatchers("/shop/admin/pay").access("hasRole('ADMIN')") // ADMIN만 가능
.antMatchers("/shop/admin/**").access("hasRole('ADMIN') or hasRole('SYS')") //ADMIN or SYS
.anyRequest().authenticated(); // 나머지 요청은 인증 처리
- 주의 : 설정시 구체적인 것이 먼저오고 큰 범위의 경로는 뒤에 와야됨, 순서대로 처리함
표현식
- anonymous() 는 익명 사용자만 혀용 USER 사용자 불가
- hasRole(String) : RoleUSER 가 있으면 Role 은 빼고 넣어야됨 Role을 같이 넣으면 안됨( 프리픽스X)
- hasAuthority(String) : 프리픽스 허용
- hasAny~~~ : 안에 있는 역할중 하나만 들어와도 허용
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user")
.password("{noop}1111").roles("USER");
auth.inMemoryAuthentication().withUser("sys")
.password("{noop}1111").roles("SYS","ADMIN");
auth.inMemoryAuthentication().withUser("admin")
.password("{noop}1111").roles("ADMIN","USER","SYS");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.antMatchers("/admin/pay").hasRole("ADMIN")
.antMatchers("/admin/**").access("hasRole('ADMIN') or hasRole('SYS')")
.anyRequest().authenticated();
http
.formLogin();
}
- 위에는 메모리에 역할을 부여한다. 나중에는 디비에 동적으로 한다
- Matcher도 나중에 동적으로 ㄱㄱ
13. 인증/인가 API - 예외 처리 및 요청 캐시 필터
FilterSecurityIntercepter
: 제일 마지막에 호출되는 클래스 이자식이 exception을 일으킴, 이 인터셉터 앞에있는 것이ExceptionTranslationFilter
이다. 이것이 try catch 문으로 인터셉터를 감싸고 있어서 인터셉터에서 예외를 던지면 필터가 잡는다**ExceptionTranslationFilter**
AuthenticationException
- 인증 예외 처리
AutheticationEntryPoint
호출- 로그인 페이지 이동, 401 오류 코드 전달 등
- 직접 인터페이스를 구현하면 커스텀하게 처리 가능
- 인증 예외가 발생하기 전의 요청 정보 저장
- user가 메인페이지 들어갈 때 로그인을 하지 않아서 거부 당하면 로그인 페이지로 이동하게된다. 이때 메인페이지를 저장하고 있다가 로그인하게 되면 바로 메인페이지로 이동 시켜줌
- RequestCache 인터페이스 구현체가 이 역할을 한다- 사용자 요청 이전 정보를 세션에 저장, SavedRequest에서 저장한 값을 세션에 저장해준다
- SavedRequest : 사용자가 이전에 요청 했던 request파라미터 값들, 그 당시 헤더 값들 저장 ( 실제로 값들이 저장 되는 곳 )
- user가 메인페이지 들어갈 때 로그인을 하지 않아서 거부 당하면 로그인 페이지로 이동하게된다. 이때 메인페이지를 저장하고 있다가 로그인하게 되면 바로 메인페이지로 이동 시켜줌
- 정리 :
AutheticationEntryPoint
를 호출해서 로그인 페이지로 이동하게 만들고 요청 전에 정보, 헤더값들을 세션에 담아놓고 필요할때 가져다 쓴다
- 인증 예외 처리
AccessDeniedExecption
- 인가 예외 처리
AccessDeniedHandler
인터페이스를 구현한 곳 에서 예외 처리하도록 제공
- 인가 예외 처리
- 사용자가 인증을 받지않고 /user 자원에 접근한다 가정
FilterSecurityIntercepter
에서 인가 예외 발생 ( 왜냐면 인증을 받지 않는 유저는 annonymous(익명사용자, 리멤버미 사용자)임 )AccessDeniedExecption
에서 Handler로 가야되지만 익명사용자나 리멤버미 사용자는AuthenticationException
간다.- 쉽게 인증 예외로 간다
AuthenticationException
에서 Security Context에 null로 초기화 시키고AutheticationEntryPoint
로 가서 login 페이지로 가게 한다- 이때 그전에 정보를 DefaultSavedRequest 객체안에 저장을 하고 Session에 저장한다. 이 역할을 HttpSessionRequestCache 가 하게 된다
- 다음 사용자는 인증은 받았는데 권한이 없는 경우 인가 예외 발동, 순서대로 간다음 보통 /denied로 가게됨.
Author And Source
이 문제에 관하여(Spring Security - 정수원 3일차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eldehd9898/Spring-Security-정수원-3일차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)