본문 바로가기

Backend/Spring | SpringBoot

[Spring Security] 인증 표현식

반응형

@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
	http
		// ...
		.authorizeHttpRequests(authorize -> authorize                                  
            .dispatcherTypeMatchers(FORWARD, ERROR).permitAll() 
			.requestMatchers("/static/**", "/signup", "/about").permitAll()         
			.requestMatchers("/admin/**").hasRole("ADMIN")                             
			.requestMatchers("/db/**").access(allOf(hasAuthority("db"), hasRole("ADMIN")))   
			.anyRequest().denyAll()                                                
		);

	return http.build();
}

로그인 처리 설정

formLogin().loginPage("/login") // 로그인 페이지로 /login으로 이동 설정
			.loginProcessingUrl("/login-process") // "/login-process"가 호출되면 인증처리를 수행하는 필터 호출
            .defaultSuccessUrl("/main") // 정상적으로 인증 성공 시 이동하는 페이지
            .successHandler(new CustomAuthenticationSuccessHandler("/main")) // 직접 구현한 커스텀 핸들러를 이용해 정상 인증 성공 후 별도 처리
            .failureUrl("/login-fail") // 인증 실패 시 이동하는 페이지
            .failureHandler(new CustomAuthenticationSuccessHandler("/login-fail")) // 직접 구현한 커스텀 핸들러를 이용해 정상 인증 실패 후 별도 처리

요청에 대한 매치 표현식의 종류는 다음과 같다.

  1. Ant를 이용한 매치 표현식
    http
        .authorizeHttpRequests((authorize) -> authorize
            //.requestMatchers("/resource/**").hasAuthority("USER") // 공식문서
            .requestMatchers(new AntPathRequestMatchers("/resource/**")).hasAuthority("USER") // URL을 ant-style을 이용해 동적으로 관리하기 위해
            .anyRequest().authenticated()
        )
        
    // 확장
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers("/resource/{name}").access(new WebExpressionAuthorizationManager("#name == authentication.name"))
            .anyRequest().authenticated()
        )​
  2. 정규식을 이용한 매치 표현식
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+")).hasAuthority("USER")
            .anyRequest().denyAll()
        )​
  3. Http Method를 이용한 매치 표현식
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(HttpMethod.GET).hasAuthority("read")
            .requestMatchers(HttpMethod.POST).hasAuthority("write")
            .anyRequest().denyAll()
        )​
  4. Dispatcher타입에 의한 매치 표현식
    http
        .authorizeHttpRequests((authorize) -> authorize
            .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
            .requestMatchers("/endpoint").permitAll()
            .anyRequest().denyAll()
        )​
  5. MvcRequestMatcher를 이용한 매치 표현식
    @Bean
    MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
    	return new MvcRequestMatcher.Builder(introspector).servletPath("/spring-mvc");
    }
    
    @Bean
    SecurityFilterChain appEndpoints(HttpSecurity http, MvcRequestMatcher.Builder mvc) {
    	http
            .authorizeHttpRequests((authorize) -> authorize
                .requestMatchers(mvc.pattern("/my/controller/**")).hasAuthority("controller")
                .anyRequest().authenticated()
            );
    
    	return http.build();
    }​
  6. 사용자 정의 매치 표현식
    RequestMatcher printview = (request) -> request.getParameter("print") != null;
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(printview).hasAuthority("print")
            .anyRequest().authenticated()
        )​
  7. 그 외
    anyRequest().authenticated() // 다른 어떤 접근에도 보안 검사 수행​

인증 요청들은 다음과 같다.

메서드 인증수준 특징
permitAll 인증 정보 검색 X 요청에 인증이 필요없음
denyAll 어떠한 경우도 요청 허용 안됨
hasAuthority GrantedAuthority를 가진 인증 요구 요청이 주어진 값과 일치
hasRole hasAuthority의 단축키,
ROLE_ 또는 설정된 기본 접두사를 붙임
hasAnyAuthority 요청이 주어진 값 중 하나와 일치
hasAnyRole hasAnyAuthority의 단축키,
ROLE_ 또는 설정된 기본 접두사를 붙임
hasPermission 객체 수준 인증 PermissionEvaluator 인스턴스로의 연결

 

 

반응형