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