This article mainly records how to customize spring Cloud OAUTH2 authentication server exception

Spring Cloud OAuth2’s default return format is not very friendly in the actual development, usually we need a uniform data return format, so that we can not be front end big brothers fun

Nonsense is just to get straight to the text

Custom exception handling

  • Edit WebResponseExceptionTranslator LwWebResponseExceptionTranslator implementation, according to the different abnormal return a status code
  • Inject LwWebResponseExceptionTranslator authentication server to replace the default DefaultWebResponseExceptionTranslator implementation

Next, look at the code. Depending on the project, there are different implementations. I’m just making a simple note that distinguishes between permission exceptions and authentication exceptions

@Slf4j public class LwWebResponseExceptionTranslator implements WebResponseExceptionTranslator { private ThrowableAnalyzer throwableAnalyzer = new ThrowableAnalyzer(); @override public ResponseEntity Translate (Exception e) throws Exception {// Obtain Exception stack information Throwable[] throwables = this.throwableAnalyzer.determineCauseChain(e); If AuthenticationException does not exist, null Exception ase = (AuthenticationException) this.throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, throwables); if (ase ! = null) { log.error(ase.getMessage()); return ResponseEntity.ok(R.failed(ResultStatus.AUTH_EXCEPTION.getCode(), ResultStatus.AUTH_EXCEPTION.getMsg())); AccessDeniedException = (AccessDeniedException); this.throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, throwables); if (ase ! = null) { log.error(ase.getMessage()); return ResponseEntity.ok(R.failed(ResultStatus.ACCESS_DENIED_EXCEPTION.getCode(), ResultStatus.ACCESS_DENIED_EXCEPTION.getMsg())); } return ResponseEntity.ok(R.failed(e.getMessage())); }}Copy the code
@constructor @allargsconstructor Public class R<T> implements Serializable { private static final long serialVersionUID = 1L; @Getter @Setter private String code; @Getter @Setter private String msg; @Getter @Setter private T data; public static <T> R<T> ok() { return restResult(null, ResultStatus.SUCCESS.getCode(), ""); } public static <T> R<T> ok(T data) { return restResult(data, ResultStatus.SUCCESS.getCode(), ""); } public static <T> R<T> ok(T data, String msg) { return restResult(data, ResultStatus.SUCCESS.getCode(), msg); } public static <T> R<T> failed() { return restResult(null, ResultStatus.SUCCESS.getCode(), ""); } public static <T> R<T> failed(String code, String msg) { return restResult(null, code, msg); } public static <T> R<T> failed(String msg) { return restResult(null, ResultStatus.FAIL.getCode(), msg); } public static <T> R<T> failed(T data) { return restResult(data, ResultStatus.FAIL.getCode(), ""); } public static <T> R<T> failed(T data, String msg) { return restResult(data, ResultStatus.FAIL.getCode(), msg); } public boolean isOk() { return this.code.equals(ResultStatus.SUCCESS.getCode()); } private static <T> R<T> restResult(T data, String code, String msg) { R<T> result = new R<>(); result.setCode(code); result.setData(data); result.setMsg(msg); return result; }}Copy the code

Custom LwWebResponseExceptionTranslator classes written, in the actual development, also can be custom exception class inheritance OAuth2Exception to do according to the different response of different abnormal return code, it would have been better Since the custom exception handling class has been completed, the following we will go to replace the original DefaultWebResponseExceptionTranslator it

/ token access endpoint configuration * * * * * @ param endpoints * / @ Override public void the configure (AuthorizationServerEndpointsConfigurer endpoints)  throws Exception { endpoints.allowedTokenEndpointRequestMethods(HttpMethod.POST, HttpMethod.GET) .authenticationManager(authenticationManagerBean) .tokenServices(tokenServices()) ExceptionTranslator (new LwWebResponseExceptionTranslator ()) / / replace exception handling class. TokenStore (tokenStore) .userDetailsService(lwUserDetailsService); }Copy the code

Results show

Little knowledge: Public Boolean isOk() {return (code, MSG,data); public Boolean isOk() {return () this.code.equals(ResultStatus.SUCCESS.getCode()); } method to determine whether the current object is successful, Lombok’s booleans default to fields with is, such as Boolean OK, and its get and set methods are isOK(). Lombok defaults my methods to fields, which is a Lombok bug