gpt4 book ai didi

Spring Security Oauth - OAuth2Exceptions 的自定义格式

转载 作者:行者123 更新时间:2023-12-04 23:14:55 26 4
gpt4 key购买 nike

spring security oauth 的错误格式符合 OAuth 规范,看起来像这样。

{
"error":"insufficient_scope",
"error_description":"Insufficient scope for this resource",
"scope":"do.something"
}

特别是在资源服务器上,我发现为身份验证问题获取不同的错误格式有点奇怪。所以我想改变这个异常的呈现方式。

documentation

Error handling in an Authorization Server uses standard Spring MVC features, namely @ExceptionHandler methods



所以我尝试了这样的事情来自定义错误的格式:
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyErrorHandler {

@ExceptionHandler(value = {InsufficientScopeException.class})
ResponseEntity<MyErrorRepresentation> handle(RuntimeException ex, HttpServletRequest request) {
return errorResponse(HttpStatus.FORBIDDEN,
MyErrorRepresentation.builder()
.errorId("insufficient.scope")
.build(),
request);
}
}

但这不起作用。

看代码,所有的错误渲染似乎都是在 DefaultWebResponseExceptionTranslator#handleOAuth2Exception中完成的.但是实现自定义 WebResponseExceptionTranslator不允许更改格式。

任何提示?

最佳答案

首先,了解一些 Spring Security OAuth2 的知识。

  • OAuth2 有两个主要部分

  • AuthorizationServer : /oauth/token, get token

    ResourceServer : url resource priviledge management


  • Spring Security 将过滤器添加到服务器容器的过滤器链中,因此 Spring Security 的异常不会到达@ControllerAdvice

  • 然后,自定义 OAuth2Exceptions 应该考虑 AuthorizationServer 和 ResourceServer。
    这是配置
    @Configuration
    @EnableAuthorizationServer
    public class OAuthSecurityConfig extends AuthorizationServerConfigurerAdapter {
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    //for custom
    endpoints.exceptionTranslator(new MyWebResponseExceptionTranslator());
    }
    }

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
    // format message
    resources.authenticationEntryPoint(new MyAuthenticationEntryPoint());
    resources.accessDeniedHandler(new MyAccessDeniedHandler());
    }
    }
    MyWebResponseExceptionTranslator 将异常转换为 ourOAuthException,我们通过 jackson 自定义 ourOAuthException 序列化程序,默认情况下 OAuth2 使用的方式相同。
    @JsonSerialize(using = OAuth2ExceptionJackson1Serializer.class)
    public class OAuth2Exception extends RuntimeException {
    其他自定义句柄类的东西
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
    import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;

    /**
    * @author qianggetaba
    * @date 2019/6/21
    */
    public class MyWebResponseExceptionTranslator implements WebResponseExceptionTranslator {
    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception exception) throws Exception {
    if (exception instanceof OAuth2Exception) {
    OAuth2Exception oAuth2Exception = (OAuth2Exception) exception;
    return ResponseEntity
    .status(oAuth2Exception.getHttpErrorCode())
    .body(new CustomOauthException(oAuth2Exception.getMessage()));
    }else if(exception instanceof AuthenticationException){
    AuthenticationException authenticationException = (AuthenticationException) exception;
    return ResponseEntity
    .status(HttpStatus.UNAUTHORIZED)
    .body(new CustomOauthException(authenticationException.getMessage()));
    }
    return ResponseEntity
    .status(HttpStatus.OK)
    .body(new CustomOauthException(exception.getMessage()));
    }
    }
    import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;

    /**
    * @author qianggetaba
    * @date 2019/6/21
    */
    @JsonSerialize(using = CustomOauthExceptionSerializer.class)
    public class CustomOauthException extends OAuth2Exception {
    public CustomOauthException(String msg) {
    super(msg);
    }
    }
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.fasterxml.jackson.databind.ser.std.StdSerializer;

    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Map;

    /**
    * @author qianggetaba
    * @date 2019/6/21
    */
    public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {

    public CustomOauthExceptionSerializer() {
    super(CustomOauthException.class);
    }

    @Override
    public void serialize(CustomOauthException value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    jsonGenerator.writeStartObject();
    jsonGenerator.writeNumberField("code4444", value.getHttpErrorCode());
    jsonGenerator.writeBooleanField("status", false);
    jsonGenerator.writeObjectField("data", null);
    jsonGenerator.writeObjectField("errors", Arrays.asList(value.getOAuth2ErrorCode(),value.getMessage()));
    if (value.getAdditionalInformation()!=null) {
    for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {
    String key = entry.getKey();
    String add = entry.getValue();
    jsonGenerator.writeStringField(key, add);
    }
    }
    jsonGenerator.writeEndObject();
    }
    }
    用于自定义 ResourceServer 异常
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    /**
    * @author qianggetaba
    * @date 2019/6/21
    */
    public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
    AuthenticationException authException)
    throws ServletException {

    Map map = new HashMap();
    map.put("errorentry", "401");
    map.put("message", authException.getMessage());
    map.put("path", request.getServletPath());
    map.put("timestamp", String.valueOf(new Date().getTime()));
    response.setContentType("application/json");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    try {
    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(response.getOutputStream(), map);
    } catch (Exception e) {
    throw new ServletException();
    }
    }

    }
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.security.access.AccessDeniedException;
    import org.springframework.security.web.access.AccessDeniedHandler;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    /**
    * @author qianggetaba
    * @date 2019/6/21
    */
    public class MyAccessDeniedHandler implements AccessDeniedHandler{
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
    response.setContentType("application/json;charset=UTF-8");
    Map map = new HashMap();
    map.put("errorauth", "400");
    map.put("message", accessDeniedException.getMessage());
    map.put("path", request.getServletPath());
    map.put("timestamp", String.valueOf(new Date().getTime()));
    response.setContentType("application/json");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    try {
    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(response.getOutputStream(), map);
    } catch (Exception e) {
    throw new ServletException();
    }
    }
    }

    关于Spring Security Oauth - OAuth2Exceptions 的自定义格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45006285/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com