Spring Boot:如何自定义禁止的错误json

时间:2018-09-26 06:32:15

标签: java spring-boot spring-security jwt

我想知道是否可以自定义以下禁止的JSON错误:

实际反应

const Card = (props) => <div className="card"><p>{props.bodytext}</p></div>

const AddButton = (props)=>{
  const addCard = (e) => {
    // Add a new <Card /> to <Page />
  }

  return <button onClick={addCard}>+</button>
}


const Page = (props) => (
  <div className="container" id="page">
    <div className="panel"><AddButton/></div>
  </div>
);

ReactDOM.render(
  <Page title="Our cards" />,
  document.getElementById('react-container')
);

自定义响应-当用户请求没有权限时,我会收到它。

"body": {
    "contentType": "html",
    "content": "<html>\r\n<head>\r\n<body>
                ...
                Judith has shared a OneDrive for Business file with you. To view it, click the link below. 
                ...
                <td width=\"0\" height=\"0\" style=\"display:none; visibility:hidden\">
                <a href=\"cid:3a24204a-f6fb-4719-97cc-0076701f2e62\">MyPresentation.pptx</a></td>
                ...
                </body>\r\n</html>\r\n"
}

我的Web安全类

{
  "timestamp": "2018-09-26T06:11:05.047+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Access Denied",
  "path": "/api/rest/hello/me"
}

3 个答案:

答案 0 :(得分:0)

要显示自定义消息,我为JWT Security创建了入口点类JwtAuthenticationEntryPoint。

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AuthenticationException e) throws IOException, ServletException {
        logger.error("Responding with unauthorized error. Message - {}", e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                "Sorry, You're not authorized to access this resource.");
    }
}

并作为入口点传递给安全配置,如

 @Configuration
 @EnableWebSecurity
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntryPoint unauthorizedHandler;

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
                    .antMatchers("auth/singIn" , "auth/singUp/")
                    .permitAll().anyRequest().authenticated();
    }
}

或者您可以使用@ControllerAdvice和自定义异常处理来处理自定义或系统异常

答案 1 :(得分:0)

您可以使用Jackson ObjectMapper创建自定义处理程序,如下所示:

@Bean
public AccessDeniedHandler accessDeniedHandler() {
    return (request, response, ex) -> {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);

        ServletOutputStream out = response.getOutputStream();
        new ObjectMapper().writeValue(out, new MyCustomErrorDTO());
        out.flush();
    };
}

并像这样配置HttpSecurity

http.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

此外,您可以尝试抛出AuthenticationException

@Bean
public AuthenticationFailureHandler failureHandler() {
    return (request, response, ex) -> { throw ex; };
}

并在@RestControllerAdvice中处理它们:

@RestControllerAdvice
public class AdviseController {

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public MyCustomErrorDTO handleAuthenticationException(AuthenticationException ex) {
        return new MyCustomErrorDTO();
    }
}

但是我不确定它是否可以工作,您可以检查一下。

答案 2 :(得分:0)

将此添加到您的控制器或 ExceptionHandler 中:

    @ExceptionHandler(AccessDeniedException.class)
    public @ResponseBody ResponseEntity<AuthzErrorResponse> handlerAccessDeniedException(final Exception ex,
            final HttpServletRequest request, final HttpServletResponse response) {

        AuthzErrorResponse authzErrorResponse = new AuthzErrorResponse();
        authzErrorResponse.setMessage("Access denied");

        return new ResponseEntity<>(authzErrorResponse, HttpStatus.FORBIDDEN);
    }

注意:AuthzErrorResponse 是我想要返回的自定义 POJO。