spring oauth2 oauthServer invalid_client Bad client credentials 自定义

spring oauth2 oauthServer 在client_id或client_secret不正确时,返回的信息不是我们需要返回的统一的json格式,spring oauth2返回的信息如下:

{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}

因此,我们需要进行自定义返回格式处理。

首先,需要自定义一个CustomClientCredentialsTokenEndpointFilter来继承ClientCredentialsTokenEndpointFilter

public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
    private final AuthorizationServerSecurityConfigurer configurer;
    private AuthenticationEntryPoint authenticationEntryPoint;

    public CustomClientCredentialsTokenEndpointFilter(AuthorizationServerSecurityConfigurer configurer) {
        this.configurer = configurer;
    }

    @Override
    public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
        this.authenticationEntryPoint = authenticationEntryPoint;
    }

    @Override
    protected AuthenticationManager getAuthenticationManager() {
        return configurer.and().getSharedObject(AuthenticationManager.class);
    }

    @Override
    public void afterPropertiesSet() {
        setAuthenticationFailureHandler((request, response, exception) -> authenticationEntryPoint.commence(request, response, exception));
        setAuthenticationSuccessHandler((request, response, authentication) -> {
            // no-op - just allow filter chain to continue to token endpoint
        });
    }
}

其次,定义CustomAuthenticationEntryPoint

@Component("customAuthenticationEntryPoint")
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.setStatus(HttpStatus.OK.value());
        R r = R.error(HttpStatus.UNAUTHORIZED.value(), "client_id或client_secret错误");
        response.setHeader("Content-Type", "application/json;charset=utf-8");

        response.getWriter().print(JSON.toJSONString(r));
        response.getWriter().flush();
    }
}

然后,在public void configure(AuthorizationServerSecurityConfigurer oauthServerSecurity) {}里边进行配置

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServerSecurity) {
        CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(oauthServerSecurity);
        endpointFilter.afterPropertiesSet();
        endpointFilter.setAuthenticationEntryPoint(customAuthenticationEntryPoint);
        // 客户端认证之前的过滤器
        oauthServerSecurity.addTokenEndpointAuthenticationFilter(endpointFilter);
    }

至次,配置完成。

注意:

此处,在configure中,不再需要配置allowFormAuthenticationForClients()。

allowFormAuthenticationForClients的作用是让/oauth/token支持client_id以及client_secret作登录认证,
oauthServerSecurity.allowFormAuthenticationForClients();即设置allowFormAuthenticationForClients = true;作用是在BasicAuthenticationFilter之前添加ClientCredentialsTokenEndpointFilter,使用ClientDetailUserDeailsService来进行client端登录的验证。

同时,使用allowFormAuthenticationForClients()和我们自定义的CustomClientCredentialsTokenEndpointFilter,会导致oauth2仍然使用allowFormAuthenticationForClients中默认的ClientCredentialsTokenEndpointFilter进行过滤,致使我们的自定义CustomClientCredentialsTokenEndpointFilter不生效。

因此,在使用CustomClientCredentialsTokenEndpointFilter时,不再需要开启allowFormAuthenticationForClients()功能。

自定义前:

自定义后:

 
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页