自定义返回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