发表于: 2018-10-18 23:30:11

1 481


今天完成的事情: 

  继续学习shiro,继续优化项目,基于URL配置权限,在本知识点就做到,如何通过URL配置来灵活设置权限,而不是非要在Controller里通过注解来做了(how2j)。

  (1)PageController.java 里原本通过注解方式的@RequiresPermissions和@RequiresRoles 注释掉;

package com.zyq.controller;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
* @autoor zyq
* @date 2018/10/16 19:47
*/
//专门用于显示页面的控制器
@Controller
@RequestMapping("")
public class PageController {
   @RequestMapping("/index")
   public String index(){
       return "index";
   }

//@RequiresPermissions("deleteOrder")
   @RequestMapping("/deleteOrder")
   public String deleteOrder(){
       return "deleteOrder";
   }

   //@RequiresRoles("admin")
   @RequestMapping("/deleteProduct")
   public String deleteProduct(){
       return "deleteProduct";
   }

   @RequestMapping("/listProduct")
   public String listProduct(){
       return "listProduct";
   }

   @RequestMapping(value="/login",method=RequestMethod.GET)
   public String login(){
       return "login";
   }

   @RequestMapping("/unauthorized")
   public String noPerms(){
       return "unauthorized";
   }
}

  (2)PermissionService.java和PermissionServiceImpl.java中增加两个方法 needInterceptor,listPermissionURLs,这里只贴出实现类中的两个方法。

@Override
public boolean needInterceptor(String requestURI) {
   List<Permission> ps = list();
   for (Permission p : ps) {
       if (p.getUrl().equals(requestURI))
           return true;
   }
   return false;
}

@Override
public Set<String> listPermissionURLs(String userName) {
   Set<String> result = new HashSet<>();
   List<Role> roles = roleService.listRoles(userName);

   List<RolePermission> rolePermissions = new ArrayList<>();

   for (Role role : roles) {
       RolePermissionExample example = new RolePermissionExample();
       example.createCriteria().andRidEqualTo(role.getId());
       List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
       rolePermissions.addAll(rps);
   }

   for (RolePermission rolePermission : rolePermissions) {
       Permission p = permissionMapper.selectByPrimaryKey(rolePermission.getPid());
       result.add(p.getUrl());
   }

   return result;
}

  (3)URLPathMatchingFilter.java,PathMatchingFilter 是shiro 内置过滤器 PathMatchingFilter 继承了这个它。

  这里简单说一下思路:拦截请求(个别除外,参见配置文件),判断用户有没有登陆,没有登陆转发至登陆页面,然后继续获取路径的URI,与从数据库中查找的所有权限对应的Url比对,若数据库中没有则方向,有,继续通过username获取相关用户的权限所对应的url与当前的请求uri比对,相同则放行,否则拦截。

package com.zyq.filter;

import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.zyq.service.PermissionService;
/**
* @autoor zyq
* @date 2018/10/18 21:08
*/
public class URLPathMatchingFilter extends PathMatchingFilter{
   @Autowired
   PermissionService permissionService;

   @Override
   protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
           throws Exception {
       String requestURI = getPathWithinApplication(request);

       System.out.println("requestURI:" + requestURI);

       Subject subject = SecurityUtils.getSubject();
       // 如果没有登录,就跳转到登录页面
       if (!subject.isAuthenticated()) {
           WebUtils.issueRedirect(request, response, "/login");
           return false;
       }

       // 看看这个路径权限里有没有维护,如果没有维护,一律放行(也可以改为一律不放行)
       boolean needInterceptor = permissionService.needInterceptor(requestURI);
       if (!needInterceptor) {
           return true;
       } else {
           boolean hasPermission = false;
           String userName = subject.getPrincipal().toString();
           Set<String> permissionUrls = permissionService.listPermissionURLs(userName);
           for (String url : permissionUrls) {
               // 这就表示当前用户有这个权限
               if (url.equals(requestURI)) {
                   hasPermission = true;
                   break;
               }
           }

           if (hasPermission)
               return true;
           else {
               UnauthorizedException ex = new UnauthorizedException("当前用户没有访问路径 " + requestURI + " 的权限");

               subject.getSession().setAttribute("ex", ex);

               WebUtils.issueRedirect(request, response, "/unauthorized");
               return false;
           }

       }

   }
}

  (4)配置文件以及jsp页面的更改参见how2j。


明天计划的事情:

  尝试将shiro与springboot相结合。


遇到的问题:

  无。


收获:

  继续学习领悟shiro框架。


返回列表 返回列表
评论

    分享到