[英]Spring Oauth2 - custom exception handler
在基于 Spring Security Oauth2 的身份验证中,当客户端发送需要刷新的访问令牌时,DefaultTokenServices 类会抛出 InvalidTokenException(参见第 235 行):
发生这种情况时的输出类似于:
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}
我想更改此输出,但我迷路了。 其他一些答案建议设立一个自定义exceptionRenderer但这并没有在这两个案例,我的自定义异常渲染器不会被调用。
还有一种叫做异常翻译器的东西,但它们在任何情况下都没有被调用。
我的弹簧配置的一部分:
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="typeName" value="Basic"/>
<property name="exceptionRenderer" ref="myExceptionRenderer" />
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="exceptionRenderer" ref="myExceptionRenderer" />
<property name="exceptionTranslator" ref="listyOauthExceptionTranslator" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" >
<property name="exceptionRenderer" ref="myExceptionRenderer" />
<property name="exceptionTranslator" ref="myExceptionTranslator" />
</bean>
<bean id="myExceptionRenderer" class="com.example.exceptions.MyOauth2ExceptionRenderer" />
<bean id="myExceptionTranslator" class="com.example.exceptions.MyOauth2ExceptionTranslator" />
异常渲染器:
public class MyExceptionRenderer implements OAuth2ExceptionRenderer {
@Override
public void handleHttpEntityResponse(HttpEntity<?> responseEntity, ServletWebRequest webRequest) throws Exception {
System.out.println("Thrown exception");
}
}
我还添加了一个自定义异常映射器,它应该获取所有异常,但是因为我假设它是另一个 servlet,所以在这种情况下它真的不起作用?
@Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable ex) {
System.out.println("MAPPING EXCEPTION");
return Response.status(200).entity().build();
}
}
我可以捕获AuthenticationException 的情况,但不能捕获任何InvalidTokenExceptions 。
对此有任何帮助吗? Spring实际上在哪里捕获这个 InvalidTokenException 以及如何设置它以便我可以提供自定义输出?
InvalidTokenException 扩展了ClientAuthenticationException
。 因此,您可以通过扩展ClientAuthenticationException
创建自己的异常并抛出它而不是InvalidTokenException
public class CustomException extends ClientAuthenticationException {
public CustomException(String msg, Throwable t) {
super(msg, t);
}
public CustomException(String msg) {
super(msg);
}
@Override
public String getOAuth2ErrorCode() {
return "my_custom_exception";
}
}
喜欢
throw new CustomException("Invalid access token: " + accessTokenValue);
在 InvalidTokenException 抛出的错误中
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"}
invalid_token
由 InvalidTokenException 和Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9
的getOAuth2ErrorCode()
方法返回Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9
是您在抛出异常时给出的消息。
如果你扔
throw new CustomException("This is my custom exception");
错误将显示为
{"error":"my_custom_exception","error_description":"This is my custom exception"}
my_custom_exception
是来自getOAuth2ErrorCode()
的CustomException
。
答案并没有真正提供自定义实现,自定义响应将是代码中的一个点,我可以在其中访问默认响应,并且可以发送 POJO 代替它,例如,如果您想将error_description
更改为error_info
或其他任何内容,或者您可能希望向响应添加更多变量。 解决方案确实存在,但我认为至少可以说实现起来很痛苦,因为我从这里复制它:
这个问题已经解决了。 请按照以下解决方法操作:
- 将
OAuth2Exception
扩展到一个新类,例如 CustomOAuth2Exception。 在自定义类中,添加一些特定的属性。- 自定义
DefaultWebResponseExceptionTranslator
并在AuthorizationServerConfiguration
注册自定义转换器。- 自定义两个在
OAuth2Exception
注释的 jackson 序列化OAuth2Exception
并使用两个自定义序列化程序注释您的CustomOAuth2Exception
。- 使用
ObjectMapper
用自定义序列化器覆盖初始序列化器。
用于覆盖
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}
您需要继承 ResourceServerConfigurerAdapter 并覆盖 public void configure(final ResourceServerSecurityConfigurer config)
示例代码
package com.org.security;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.stereotype.Component;
@Component
public class CustomWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {
/**
* Modify OAuth2.0 Error Response
* @param e
* @return ResponseEntity<OAuth2Exception>
* @throws Exception
*/
@Override
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
ResponseEntity responseEntity = super.translate(e);
OAuth2Exception auth2Exception = (OAuth2Exception)responseEntity.getBody();
if (auth2Exception != null) {
auth2Exception.addAdditionalInformation("data", null);
auth2Exception.addAdditionalInformation("message", auth2Exception.getMessage());
auth2Exception.addAdditionalInformation("statusCode", String.valueOf(auth2Exception.getHttpErrorCode()));
}
return new ResponseEntity<OAuth2Exception>(auth2Exception, responseEntity.getHeaders(), responseEntity.getStatusCode());
}
}
package com.org.security;
import com.org.exception.CustomAuthExceptionEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private ResourceServerTokenServices tokenServices;
@Autowired
private WebResponseExceptionTranslator oauth2ResponseExceptionTranslator;
@Override
public void configure(final ResourceServerSecurityConfigurer config) {
OAuth2AccessDeniedHandler auth2AccessDeniedHandler = new OAuth2AccessDeniedHandler();
auth2AccessDeniedHandler.setExceptionTranslator(oauth2ResponseExceptionTranslator);
OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
authenticationEntryPoint.setExceptionTranslator(oauth2ResponseExceptionTranslator);
config.tokenServices(tokenServices).accessDeniedHandler(auth2AccessDeniedHandler).authenticationEntryPoint(authenticationEntryPoint);
}
}
这是我对自定义 AuthorizationServer 和 ResourceServer 异常的解决方案。 可能会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.