发表于: 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框架。
评论