开发者社区> 问答> 正文

oauth2怎么自定义token失效的响应异常信息 - oauth2报错

{
    "error": "invalid_token",
    "error_description": "6610c99d-505c-4f80-927c-a5d23c0e54cb"
}

 

想自定义成中文

关于这个博客的方法

https://my.oschina.net/merryyou/blog/1819572https://my.oschina.net/merryyou/blog/1819572

其他比如账户过期这种返回的自定义信息已经成功了,

就是没办法定义成功token失效信息。

也就是教程中的AuthExceptionEntryPoint 这个类。当发送一个无效token请求时,这个方法明明已经进去了。

public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws ServletException {

		Map map = new HashMap();
		map.put("error", "401111111");
		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();
		}
	}
}

但是返回的还是这种

{
    "error": "invalid_token",
    "error_description": "6610c99d-505c-4f80-927c-a5d23c0e54cb"
}

另外在 ResourceServerConfigurerAdapter 和 ClientDetailsServiceConfigurer 中都设置了这个入口类,就是不成功,谁能告诉我咋办呀

展开
收起
montos 2020-05-31 22:08:52 1386 0
1 条回答
写回答
取消 提交回答
  • invalid_token有很多处都会抛出。建议你去了解一下Spring 国际化方法

    ######

    我也是根据那个博客改造的返回信息,开始也折腾了很久,就是不成功,后来开窍了,搞好了,

    我们架构是微服务架构,权限是一个服务,其他资源服务的权限验证放在网关上,开始我是作死地改造权限服务的返回,搞死了没反应,后来一想客户端的权限都是网关做的,所以开始在网关上搞事情,一下就OK了,没有博客上写的那么复杂,就简单加了2个类,一个配置,简述如下(记得在资源服务中加,不是权限服务):

    第一个类:无效token 异常重写

    public class AuthExceptionEntryPoint implements AuthenticationEntryPoint
    {

        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws ServletException {
            Map<String, Object> map = new HashMap<String, Object>();
            Throwable cause = authException.getCause();
            if(cause instanceof InvalidTokenException) {
                map.put("code", RespCode.INVALID_TOKEN);//401
                map.put("msg", "无效的token");
            }else{
                map.put("code", RespCode.UN_LOGIN);//401
                map.put("msg", "访问此资源需要完全的身份验证");
            }
            map.put("data", authException.getMessage());
            map.put("success", false);
            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();
            }
        }
    }

    第二个类:权限不足异常类重写

    @Component("customAccessDeniedHandler")
    public class CustomAccessDeniedHandler implements AccessDeniedHandler {

        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException)
            throws IOException, ServletException {
            response.setContentType("application/json;charset=UTF-8");
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("code", RespCode.UNAUTHORIZED);//401
            map.put("msg", "权限不足");
            map.put("data", accessDeniedException.getMessage());
            map.put("success", false);
            map.put("path", request.getServletPath());
            map.put("timestamp", String.valueOf(new Date().getTime()));
            ObjectMapper mapper = new ObjectMapper();
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write(mapper.writeValueAsString(map));
        }
    }

    3)关键配置,在资源配置类中,重写方法:

    public class ResourceServerConfig extends ResourceServerConfigurerAdapter
    {
        @Autowired
        TokenStore tokenStore;
        
        @Override
        public void configure(HttpSecurity http) throws Exception {
            (省略)
        }
        
        @Override
        public void configure(ResourceServerSecurityConfigurer resource) throws Exception {

            //这里把自定义异常加进去
            resource.tokenStore(tokenStore).authenticationEntryPoint(new AuthExceptionEntryPoint())
                .accessDeniedHandler(new CustomAccessDeniedHandler());
        }

    }

    ######好人啊,这个卡在网关 了,不用网关直接访问,就是自定义的了,,######

    你好,这个问题解決了嗎?

    ######

    引用来自“半夏琉璃”的评论

    我也是根据那个博客改造的返回信息,开始也折腾了很久,就是不成功,后来开窍了,搞好了,

    我们架构是微服务架构,权限是一个服务,其他资源服务的权限验证放在网关上,开始我是作死地改造权限服务的返回,搞死了没反应,后来一想客户端的权限都是网关做的,所以开始在网关上搞事情,一下就OK了,没有博客上写的那么复杂,就简单加了2个类,一个配置,简述如下(记得在资源服务中加,不是权限服务):

    第一个类:无效token 异常重写

    public class AuthExceptionEntryPoint implements AuthenticationEntryPoint
    {

        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws ServletException {
            Map<String, Object> map = new HashMap<String, Object>();
            Throwable cause = authException.getCause();
            if(cause instanceof InvalidTokenException) {
                map.put("code", RespCode.INVALID_TOKEN);//401
                map.put("msg", "无效的token");
            }else{
                map.put("code", RespCode.UN_LOGIN);//401
                map.put("msg", "访问此资源需要完全的身份验证");
            }
            map.put("data", authException.getMessage());
            map.put("success", false);
            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();
            }
        }
    }

    第二个类:权限不足异常类重写

    @Component("customAccessDeniedHandler")
    public class CustomAccessDeniedHandler implements AccessDeniedHandler {

        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException)
            throws IOException, ServletException {
            response.setContentType("application/json;charset=UTF-8");
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("code", RespCode.UNAUTHORIZED);//401
            map.put("msg", "权限不足");
            map.put("data", accessDeniedException.getMessage());
            map.put("success", false);
            map.put("path", request.getServletPath());
            map.put("timestamp", String.valueOf(new Date().getTime()));
            ObjectMapper mapper = new ObjectMapper();
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write(mapper.writeValueAsString(map));
        }
    }

    3)关键配置,在资源配置类中,重写方法:

    public class ResourceServerConfig extends ResourceServerConfigurerAdapter
    {
        @Autowired
        TokenStore tokenStore;
        
        @Override
        public void configure(HttpSecurity http) throws Exception {
            (省略)
        }
        
        @Override
        public void configure(ResourceServerSecurityConfigurer resource) throws Exception {

            //这里把自定义异常加进去
            resource.tokenStore(tokenStore).authenticationEntryPoint(new AuthExceptionEntryPoint())
                .accessDeniedHandler(new CustomAccessDeniedHandler());
        }

    }

    按你的方法解决了,太好了,赞

    2020-05-31 22:09:16
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载