一、问题引入
使用前端页面来测试效果的时候,发现退出登录功能存在问题,页面显示没有权限操作:
使用postman测试:
二、分析问题
这里让我很迷惑,因为我明白这是后端出现问题了,并且很明显是权限那块的问题,可是我做这个前台项目还未涉及到权限,只涉及到认证,所以它如果报错的话,也不应该是报403的错,因为这个403的错,以及错误信息,是因为我设置了权限不足处理器处理的原因,如下图:
@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
ResponseResult responseResult = ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
String json = JSON.toJSONString(responseResult);
WebUtils.renderString(httpServletResponse,json);
}
}
所以一定是缺少权限的原因,这里就是我的困惑点了,因为我在我的前台后端代码中,还从未涉及到权限管理,根本就没为退出登录接口设置权限,也没从数据库中查询用户的权限,反正权限代码是一点都没有。因为这个问题,我找了好久的原因,后端代码看了好几遍,看了退出的实现看了好几遍,可其实退出那里的逻辑实际上都没执行。最后不知道怎么回事,在群里向别人请求才知道问题所在,通过看他security配置,和我的进行对比,才知道我少了这一句:
http.logout().disable();
其实后面想想确实也是这么一回事,为什么没走我的退出登录的逻辑,而反过去执行其它逻辑,这里的其它逻辑,既然不是我写的,那么也就是security内置的退出逻辑了,它那个退出登录接口应该是设置了权限的,所以这也就是为什么我走退出登录一直没权限的原因。
三、解决问题
只需在securityConfigure里面添加这一句即可:
protected void configure(HttpSecurity http) throws Exception {
//关闭csrf
http.csrf().disable()
//不能通过session获取securityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
//对于登录接口,允许匿名访问
.antMatchers("/login").anonymous()
.antMatchers("/logout").authenticated()
.antMatchers("/user/userInfo").authenticated()
//除上面之外的所有请求都不需要认证即可访问
.anyRequest().permitAll();
http.cors();
//注册过滤器
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
//关闭默认的退出,关键的一句
http.logout().disable();
//注册认证异常和权限异常处理器
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
}
http.logout().disable();
关闭security默认的退出登录即可,让security走我自己的退出逻辑
四、总结
其实还是自己对于这个不是很敏感,其实是很简单的,我的代码没设置权限,真正运行却走了权限,这很明显的就是跳过了我的逻辑,执行了security的逻辑,其实还是思维狭窄了,确实是,自始至终只想到自己的代码,而从未考虑是不是执行了别人的代码,这次也是吸取教训了