티스토리 뷰

DefaultLoginPageGeneratingFilter

  • GET /login 처리
  • 별도의 로그인 페이지를 설정하지 않으면 제공되는 필터
  • 기본 로그인 form 제공
  • OAuth2 / OpenID / Saml2 로그인과 같이 사용가능

UsernamePasswordAuthenticationFilter

  • 폼 로그인을 처리하는 필터
  • POST /login(default) 처리 (processingUrl 변경시 로그인 주소 변경 가능)
  • form 인증을 처리하는 필터
UsernamePasswordAuthenticationFilter 의 주요 설정 정보
  1. filterProcessingUrl : 로그인을 처리해 줄 URL (POST)
  2. username parameter : POST에 username 에 대한 값을 넘겨줄 인자의 이름
  3. password parameter : POST에 password 에 대한 값을 넘겨줄 인자의 이름
  4. 로그인 성공 및 실패시 처리 방법
    1. defaultSuccessUrl : alwaysUse 중요
    2. successHandler 
    3. failUrl
    4. failHandler
  5. authenticationDetailSource : Authentication 객체의 details 에 들어갈 정보를 직접 생성
    • details 에 요청 클라이언트의 IP를 담아두면 authenticate 에서 요청에 대한 거부 가능
@Override
public Authentication attemptAuthentication(HttpServletRequest request, 
HttpServletResponse response)
		throws AuthenticationException {
	// 요청 method 가 POST 가 아니라면 예외처리
	if (this.postOnly && !request.getMethod().equals("POST")) {
		throw new AuthenticationServiceException("Authentication method 
        not supported: " + request.getMethod());
	}
	// request 에서 사용자 id 가져옴
	String username = obtainUsername(request);
	username = (username != null) ? username : "";
	username = username.trim();
	
	// request 에서 사용자 pw 가져옴
	String password = obtainPassword(request);
	password = (password != null) ? password : "";
	
	// id/pw 를 가지고 UsernamePasswordAuthenticationToken 생성
	UsernamePasswordAuthenticationToken authRequest = 
    new UsernamePasswordAuthenticationToken(username, password);
	// detail 생성
	setDetails(request, authRequest);
	// UsernamePasswordAuthenticationToken 을 인증 매니저에게 넘겨서 인증 과정 위임
	// AuthenticationManager 는 해당 인증을 처리할 수 있는 AuthenticationProvider를 
    // 찾고 인증 위임
	return this.getAuthenticationManager().authenticate(authRequest);
}

Form login 요구사항 분석

1. 사용자는 일반 사용자/관리자 2가지 종류

2. 일반 사용자/관리자 모두 /index 메인 페이지로 접속 & 사용자의 권한이 없다면 /access_Deny 페이지로 이동

3. 일반 사용자는 메인 페이지에서 /user-page 로 이동하고 관리자는 /admin-page 로 이동

4. 로그인에 성공하면 / 메인페이지로, 로그인에 실패하면 /login-error 페이지로 이동

5. ADMIN 권한을 가진 사용자는 일반 USER 권한도 가져야함(?) -> user 는 admin 페이지를 볼 수 없지만 admin user 는 admin, user 페이지 모두 볼 수 있어야 함

1번 요구사항을 위한 설정

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser(
                        User.withDefaultPasswordEncoder()
                                .username("user1")
                                .password("1111")
                                .roles("USER")
                ).withUser(
                        User.withDefaultPasswordEncoder()
                                .username("admin")
                                .password("2222")
                                .roles("ADMIN")
                );
    }

메모리에 USER 권한을 가진 user1, ADMIN 권한을 가진 admin 생성. 패스워드는 DefaultPasswordEncoder 사용

 

2번/4번 요구사항을 위한 설정

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests(request->{
                    request
                            .antMatchers("/").permitAll()
                            .anyRequest().authenticated()
                            ;
                })
                .formLogin(
                        login->login.loginPage("/login")
                                .permitAll()
                                .defaultSuccessUrl("/", false)
                                .failureUrl("/login-error")
                                .authenticationDetailsSource(customAuthDetails)
                        )
                        .logout(logout->logout.logoutSuccessUrl("/"))
                .exceptionHandling(exception->exception.accessDeniedPage("/access-denied"))
                ;
    }
  • 접근 권한이 넓은 것 부터 작은 순으로 설정해야한다. antMatchers 를 통해 root path 에 대해서는 모든 유저가 접근 할 수 있도록 하였고(접근 권한 범위가 넓음), anyRequest().authenticated() 를 통해 요청의 권한을 확인. 
  • formLogin 을 통해 로그인 페이지를 지정하였고 모든 권한의 user가 접근할 수 있도록 설정
  • defaultSuccessUrl은 로그인 성공시 첫번째 파라미터로 넣은 홈 디렉토리로 이동하겠다는 뜻이고 두번째 파라미터가 true 일 때 항상 첫번째 파라미터로 지정한 경로로 이동하겠다는 뜻이고 false 라면 항상 지정한 경로로 가지 않겠다는 의미
  • failureUrl 은 로그인 실패시 이동할 경로를 지정해주는 것
  • authenticationDetailSource 는 Authentication 객체에 user id, pw 뿐만아니라 다른 정보를 포함시키기 위한 설정(ip, 로그인 요청 시간, 세션 ID)
  • logout 은 로그아웃 성공시 이동할 경로를 지정
  • exceptionHandling 을 통해 예외 발생시(권한이 없는 페이지에 접근) 이동할 페이지를 지정할 수 있음

5번 요구사항을 위한 설정

@Bean
    RoleHierarchy roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
        return roleHierarchy;
    }
  • RoleHirearchy 를 사용하면 권한의 계층구조를 만들 수 있음 setHierarchy 는 ROLE_A >  ROLE_B > ROLE_C 비교 연산자를 통해서 권한이 많고 적음을 설정할 수 있음
  • ADMIN 은 USER/ADMIN 권한 두가지 모두 가질 수 있기 때문에 USER 보다 크다고(?) 표현할 수 있음
  • 다음과 같이 설정하면 ADMIN 은 USER 페이지에도 접근할 수 있게 됨

권한이 없어 Resource 가 적용되지 않는 경우

@Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .requestMatchers(
                        PathRequest.toStaticResources().atCommonLocations()
                );
    }
  • WebSecurity 설정은 Security 보다 앞단을 설정할 수 있음
  • 프론트 resources Security Filter 에 걸리면 css 가 적용안되는 경우가 있을 수 있기 때문에 다음과 같은 설정으로 정적 리소스는 예외처리를 시켜줘야함

WebSecurity 설정

  • Spring Security 앞단을 설정

HttpSecurity 설정

  • URL 접근 권한 설정
  • 인증 로직 커스텀을 위한 필터 설정
  • 전체적인 인증 흐름 설정 

'패캠강의정리' 카테고리의 다른 글

[Spring Security] Spring Security 개요  (0) 2022.08.06
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함