๐Ÿ’ Spring/Spring Security

Spring Security Error Code ๋ณ„ ํŽ˜์ด์ง€ ์ฒ˜๋ฆฌํ•˜๊ธฐ

iseunghan 2022. 6. 21. 23:54
๋ฐ˜์‘ํ˜•

Spring boot + Security ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์—๋Ÿฌ ์ฝ”๋“œ ๋งˆ๋‹ค ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€๋ฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋Š”์ง€ ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด๋ณด๋‹ค๊ฐ€ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์ƒ๊ฐ๋‚ฌ์Šต๋‹ˆ๋‹ค.

1. EntryPoint, Handler ์‚ฌ์šฉ

authenticationEntryPoint, accessDeniedHandler์—์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•ด๋‹น ์—๋Ÿฌ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Security Config

/* Security Config */
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                    // ..
                    .exceptionHandling()
                    .authenticationEntryPoint(new MyAuthenticationEntryPoint())
                    .accessDeniedHandler(new MyAccessDeniedHandler())
                    // ..
        ;
    }

AuthenticationEntryPoint

public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.sendRedirect("/unauthorized");
    }
}

AccessDeniedHandler

public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.sendRedirect("/access-denied");
    }
}

Controller ์ฝ”๋“œ ์ถ”๊ฐ€

public class MyErrorController {

    @GetMapping("/unauthorized")
    public String unauthorizedPage() {
        return "/todoList/unauthorized";
    }

    @GetMapping("/access-denied")
    public String accessDeniedPage() {
        return "/todoList/access-denied";
    }
}

๊ฐ ์—๋Ÿฌ ํŽ˜์ด์ง€ ์ƒ์„ฑ (์ƒ๋žต)

ํ•ด๋‹น ์—๋Ÿฌ ๋‚ด์šฉ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

2. Spring Security์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ ์‚ฌ์šฉ

์ฐพ์•„๋ณด๋‹ˆ๊นŒ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์—์„œ ErrorController ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ์—๋Ÿฌ ํŽ˜์ด์ง€๋งˆ๋‹ค ์ผ์ผํžˆ API๋ฅผ ์ƒ์„ฑํ•  ํ•„์š” ์—†์ด ํ•˜๋‚˜์˜ API์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Controller
public class HomeController implements ErrorController {

    /* ๊ตฌํ˜„ ํ•ด์•ผํ•˜๋Š” ๋ฉ”์†Œ๋“œ */
    @Override
    public String error() {
        return "/error";
    }

    /* error๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ */
    @GetMapping("/error")
    public String error(HttpServletRequest request) {
        Integer errorCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

        /* Error Code ๋ณ„๋กœ ํŽ˜์ด์ง€ ์ œ๊ณต */
        switch (errorCode){
            case 401:
                return "/unauthorized";
            case 403:
                return "/access-denied";
            case 404:
                return "/not-found";
            default:
                return "/server-error";
        }
    }
}

 

์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”?

Spring ๊ธฐ๋ณธ error page

์œ„ Whitelabel Error Page๋Š” BasicErrorController๊ฐ€ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ErrorMvcAutoConfiguration์ด๋ผ๋Š” ํด๋ž˜์Šค์—์„œ BasicErrorController๋ฅผ ๋นˆ์œผ๋กœ ๋งŒ๋“œ๋Š”๋ฐ ์ด๋•Œ @ConditionalOnMissingBean์ด ๋ถ™์–ด์žˆ์–ด์„œ ErrorController๊ฐ€ ์—†์„ ๋•Œ ๋นˆ์œผ๋กœ ๋“ฑ๋ก์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์œ„์—์„œ ErrorController๋ฅผ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— BasicErrorController๊ฐ€ ๋นˆ์œผ๋กœ ๋“ฑ๋ก์ด ์•ˆ๋˜์—ˆ๊ณ , ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ ์—๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@AutoConfiguration(before = WebMvcAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
@EnableConfigurationProperties({ ServerProperties.class, WebMvcProperties.class })
public class ErrorMvcAutoConfiguration {

	// ์ƒ๋žต..
    
	@Bean
	@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
	public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,
			ObjectProvider<ErrorViewResolver> errorViewResolvers) {
		return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
				errorViewResolvers.orderedStream().collect(Collectors.toList()));
	}
    
    // ..   
}

REFERENCES

 

 
๋ฐ˜์‘ํ˜•