springboot 集成 shiro 前后端分离 返回认证鉴权JSON数据

自定义返回JSON数据主要配置如下地方:

在ShiroConfig中修改如下:

@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//安全管理器配置
shiroFilterFactoryBean.setSecurityManager(securityManager);
//自定义用户拦截器
LinkedHashMap<String, Filter> map = new LinkedHashMap<>();
map.put("authc", new ShiroLoginFilter());对应//shiroFilterFactoryBean.setLoginUrl("/login");
    map.put("roles",new ShiroAuthorizationFilter()); 对应 //shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
shiroFilterFactoryBean.setFilters(map);

Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/api/**", "anon");
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
filterChainDefinitionMap.put("/**", "authc");
//filterChainDefinitions 配置过滤规则,从上到下的顺序匹配
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;

}

添加两个类:ShiroLoginFilter / ShiroAuthorizationFilter,CommonResult类是我封装的统一返回格式,可以自行修改
public class ShiroLoginFilter extends FormAuthenticationFilter {

/**
* 当shiro校验用户未登录时,返回JSON数据代替原有的跳转到登录界面
* @param servletRequest
* @param servletResponse
* @throws IOException
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
httpServletResponse.setStatus(200);
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();

String json = JSON.toJSONString(CommonResult.Error_User_Unlogin_100108);

out.write(json);
out.flush();
out.close();
return false;
}

}
public class ShiroAuthorizationFilter extends RolesAuthorizationFilter {

/**
* 校验用户权限,当无权限时返回JSON数据代替原有的跳转到界面
* @param servletRequest
* @param servletResponse
* @return
* @throws IOException
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
httpServletResponse.setStatus(200);
httpServletResponse.setContentType("application/json; charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
Subject subject = getSubject(servletRequest, servletResponse);

String json;
if (subject.getPrincipal() == null) {
// 没有认证,先返回未认证的json
json = JSON.toJSONString(CommonResult.Error_User_Unlogin_100108);
} else {
// 已认证但没有角色,返回为授权的json
json = JSON.toJSONString(CommonResult.Error_User_NORights_100109);
}

out.write(json);
out.flush();
out.close();
return false;
}

}

最后还有一个关键的地方需要配置,yml 配置文件中,需要添加如下配置:
spring:
  mvc:
    throw-exception-if-no-handler-found: true
  resources:
  add-mappings: false


上一篇:ServletResponse


下一篇:spring security 自定义退出策略