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");
}
}
また、すべての例外を取得するカスタム例外マッパーを追加しましたが、別のサーブレットを想定しているため、この場合は実際には機能しませんか?
@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の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
_はCustomException
のgetOAuth2ErrorCode()
から来ています。
答えは実際にはカスタム実装を提供しません。カスタム応答は、デフォルトの応答にアクセスでき、代わりにPOJOを送信できるコード内のポイントになります。たとえば、error_description
をerror_info
などに変更する場合、または応答に変数を追加することもできます。解決策は存在しますが、 ここ からコピーするので、控えめに言っても実装するのは苦痛だと思います。
この問題は解決されました。以下の回避策に従ってください。1OAuth2ExceptionをCustomOAuth2Exceptionなどの新しいクラスに拡張します。カスタムクラスで、いくつかの特定のプロパティを追加します。 2カスタムDefaultWebResponseExceptionTranslatorを実行し、AuthorizationServerConfigurationにカスタムトランスレータを登録します。 OAuth2Exceptionで注釈が付けられ、CustomOAuth2Exceptionに2つのカスタムシリアライザーで注釈が付けられた3つのカスタム2つのジャクソンシリアライザー。 4 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例外に対する私のソリューションです。それが役立つかもしれません。