java Spring Oauth2 - 自定义异常处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31660707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Oauth2 - custom exception handler
提问by breakline
In Spring Security Oauth2 based authentication when the client sends an access token which needs to be refreshed, the DefaultTokenServices class throws an InvalidTokenException (see at line 235):
在基于 Spring Security Oauth2 的身份验证中,当客户端发送需要刷新的访问令牌时,DefaultTokenServices 类会抛出 InvalidTokenException(参见第 235 行):
the output when this happens is something like:
发生这种情况时的输出类似于:
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}
I'd like to change this output but I got lost. Some other answer suggested setting up a custom exceptionRendererbut this didn't work either, my custom exception renderer never gets called in these cases.
我想更改此输出,但我迷路了。其他一些答案建议设立一个自定义exceptionRenderer但这并没有在这两个案例,我的自定义异常渲染器不会被调用。
Also there's something called an exception translatorbut they werent called either in any case.
还有一种叫做异常翻译器的东西,但它们在任何情况下都没有被调用。
Part of my spring config:
我的弹簧配置的一部分:
<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" />
The exception renderer:
异常渲染器:
public class MyExceptionRenderer implements OAuth2ExceptionRenderer {
@Override
public void handleHttpEntityResponse(HttpEntity<?> responseEntity, ServletWebRequest webRequest) throws Exception {
System.out.println("Thrown exception");
}
}
}
I also added a custom Exception Mapper which should get ALL the exceptions, but since I assume its another servlet this doesnt really work in this case?
我还添加了一个自定义异常映射器,它应该获取所有异常,但是因为我假设它是另一个 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();
}
}
I could catch cases of AuthenticationException, but not any of the InvalidTokenExceptions.
我可以捕获AuthenticationException 的情况,但不能捕获任何InvalidTokenExceptions。
Any help regarding this? Where does Spring actually catch this InvalidTokenException and how can I set it up so I can provide a custom output?
对此有任何帮助吗?Spring实际上在哪里捕获这个 InvalidTokenException 以及如何设置它以便我可以提供自定义输出?
采纳答案by Karthik
InvalidTokenException extends ClientAuthenticationException
. So you can create your own exception by extending ClientAuthenticationException
and throw this instead of 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";
}
}
like
喜欢
throw new CustomException("Invalid access token: " + accessTokenValue);
In the error that is thrown by InvalidTokenException
在 InvalidTokenException 抛出的错误中
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"}
invalid_token
is returned by getOAuth2ErrorCode()
method of InvalidTokenException and Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9
is the message that you give when you throw the exception.
invalid_token
由getOAuth2ErrorCode()
InvalidTokenException 方法返回,Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9
是您在抛出异常时给出的消息。
If you throw
如果你扔
throw new CustomException("This is my custom exception");
the error would be shown as
错误将显示为
{"error":"my_custom_exception","error_description":"This is my custom exception"}
my_custom_exception
is coming from getOAuth2ErrorCode()
of CustomException
.
my_custom_exception
是从哪里来getOAuth2ErrorCode()
的CustomException
。
回答by Hasson
The answer does not really deliver custom implementation, a custom response will be a point in code where I can access the default response and I can send a POJO instead of it, for example if you want to change error_description
to error_info
or anything else, or you may want to add more variables to the response. The solution does exist, but I think it is painful to implement to say the least, as I copy it from here:
答案并没有真正提供自定义实现,自定义响应将是代码中的一个点,我可以在其中访问默认响应,并且我可以发送 POJO 代替它,例如,如果您想更改error_description
为error_info
或其他任何内容,或者您可能想要向响应添加更多变量。解决方案确实存在,但我认为至少可以说实现起来很痛苦,因为我从这里复制它:
This problem has been solved. Follow the workaround below:
- Extend
OAuth2Exception
to a new class, such as CustomOAuth2Exception. In the custom class, add some specific properties.- custom
DefaultWebResponseExceptionTranslator
and register the custom translator inAuthorizationServerConfiguration
.- custom two Hymanson serializers annotated in
OAuth2Exception
and annotated yourCustomOAuth2Exception
with the two custom serializers.- use
ObjectMapper
to override initial serializers with custom serializers.
这个问题已经解决了。请按照以下解决方法操作:
- 扩展
OAuth2Exception
到一个新的类,比如 CustomOAuth2Exception。在自定义类中,添加一些特定的属性。- 自定义
DefaultWebResponseExceptionTranslator
并在AuthorizationServerConfiguration
.- 自定义两个 Hymanson 序列化程序,
OAuth2Exception
并使用CustomOAuth2Exception
两个自定义序列化程序注释您。- 用于使用
ObjectMapper
自定义序列化程序覆盖初始序列化程序。
回答by rohit prakash
for overriding
用于覆盖
{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}
you need to inherit ResourceServerConfigurerAdapter and override public void configure(final ResourceServerSecurityConfigurer config)
您需要继承 ResourceServerConfigurerAdapter 并覆盖 public void configure(final ResourceServerSecurityConfigurer config)
sample code
示例代码
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);
}
}
回答by Luke Cheung
This my solution to custom AuthorizationServer and ResourceServer exception. May be it will help.
这是我对自定义 AuthorizationServer 和 ResourceServer 异常的解决方案。可能会有所帮助。