복붙노트

[SPRING] @RestController로 봄 보안 - JSONish CustomAuthenticationProvider 응답

SPRING

@RestController로 봄 보안 - JSONish CustomAuthenticationProvider 응답

나는 봄, 특히 봄 보안에 관해서는 새로운 것입니다. 이 응용 프로그램은 편안한 응용 프로그램입니다.

다음은 @RestController의 스 니펫입니다.

@RequestMapping(value = "/new", method = RequestMethod.POST)
    @PreRegistration("new")
    @ResponseBody
    public ResponseEntity<Void> newUser(@RequestBody @Valid TempUser user, UriComponentsBuilder ucBuilder) {

        registerService.addUser(user);

        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/register/{userName}").buildAndExpand(user.getUserName()).toUri());
        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
    }

CustomAuthenticationProvider의 스 니펫은 다음과 같습니다.

@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException  {
    final String name = authentication.getName();
    final String password = authentication.getCredentials().toString();
    if (name.equals("admin") && password.equals("system")) {
        final List<GrantedAuthority> grantedAuths = new ArrayList<>();
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
        final UserDetails principal = new User(name, password, grantedAuths);
        final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
        return auth;
    } 
    else {
        throw new BadCredentialsException("NOT_AUTHORIZED");
    }
}

SecurityConfig :

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .requestCache()
            .requestCache(new NullRequestCache())
            .and()
        .httpBasic()
            .and()
        .csrf().disable();
}

내가 성취하려고하는 것은 CustomAuthenticationProvider가 예외 (예 : "나쁜 인증"또는 "전체 인증 필요 ...")을 발생 시켰을 때 응답을 사용자 정의하고 JSON 형식의 응답 본문으로 반환하고자합니다.

내가 한 것은 새로운 예외를 만들고 AOP를 사용하여 호출하는 것입니다. 그러나 그것은 작동하지 않는 것 같습니다. 또한 @ControllerAdvice를 사용하려고 시도했지만 CustomAuthenticationProvider가 컨트롤러 외부에 있기 때문에 잘 작동하지 않는 것처럼 보입니다.

해결법

  1. ==============================

    1.이것을위한 더 좋은 방법이 있습니다. AuthenticationEntryPoint 인터페이스를 구현하는 Spring 보안 구성 및 클래스에 authenticationEntryPoint를 추가해야합니다. 이 같은:

    이것을위한 더 좋은 방법이 있습니다. AuthenticationEntryPoint 인터페이스를 구현하는 Spring 보안 구성 및 클래스에 authenticationEntryPoint를 추가해야합니다. 이 같은:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
            .requestCache()
                .requestCache(new NullRequestCache())
                .and()
            .httpBasic()
            // --> begin change: new lines added
                .and()
            .exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint())
            // <-- end change
                .and()
            .csrf().disable();
    

    }

    JSON 생성을위한 AuthExceptionEntryPoint 클래스 Jackson Jackson 사용 된 ObjectMapper :

    public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response, 
                             AuthenticationException authException) 
                             throws IOException, ServletException {
    
            List<String> errors = new ArrayList<>();
            errors.add("Unauthorized");
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            try {
                ObjectMapper mapper = new ObjectMapper();
                mapper.writeValue(response.getOutputStream(), errors);
            } catch (Exception e) {
                throw new ServletException();
            }
        }
    }
    

    Spring 보안 설정에 대한 더 많은 정보는 Spring 문서에서 읽을 수있다.

  2. ==============================

    2.다음과 같은 방법으로 구성 파일에서 AccessDeniedException을 catch하고 ExceptionTranslationFilter 다음에 필터를 추가 할 수있는 사용자 지정 필터를 만들 수 있습니다.

    다음과 같은 방법으로 구성 파일에서 AccessDeniedException을 catch하고 ExceptionTranslationFilter 다음에 필터를 추가 할 수있는 사용자 지정 필터를 만들 수 있습니다.

    http.addFilterAfter(customExceptionTranslationFilter, ExceptionTranslationFilter.class)
    

    예외를 포착 한 후에는 응답 객체를 사용하여 원하는 방식으로 응답 할 수 있습니다.

    그런 다음 컨트롤러에 던져 넣을 수있는 다른 예외로 작업 할 수있는 기능을 추가 할 수 있습니다.

  3. from https://stackoverflow.com/questions/37063342/spring-security-with-restcontroller-jsonish-customauthenticationprovider-resp by cc-by-sa and MIT license