1.项目中添加权限
shiro处理权限流程:
(1)把所有的权限交给shiro管理 --createFilterChainDefinitionMap 可以体现处理
(2)在realm里面 就要查询当前用户的权限,如果这个权限在shiro管理返回之内,这个用户就有响应的权限
否则就没有
1.1.获取到所有权限交给shiro管理
List<Permission> permissions = permissionService.findAll();
for (Permission permission : permissions) {
String url = permission.getUrl();
String sn = permission.getSn();
map.put(url, "aisellPerms["+permission.getSn()+"]");
}
1.2.查询当前用户具备哪些权限
PermissionRepository
public interface PermissionRepository extends BaseRepository<Permission,Long> {
//查询当前用户的权限
@Query("select distinct p.sn from Employee e join e.roles er join er.permissions p where e.id = ?1")
public Set<String> findPermissionByEmployeeId(Long id);
}
IPermissionService
public interface IPermissionService extends IBaseService<Permission,Long> {
public Set<String> findPermissionByEmployeeId(Long id);
}
PermissionServiceImpl
@Service
public class PermissionSerivceImpl extends BaseServiceImpl<Permission,Long> implements IPermissionService{
@Autowired
private PermissionRepository permissionRepository;
//查询当前用户多对应的权限
@Override
public Set<String> findPermissionByEmployeeId(Long id) {
return permissionRepository.findPermissionByEmployeeId(id);
}
}
再进行判断
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//授权方法
Employee employee = (Employee)principalCollection.getPrimaryPrincipal();
//根据用户名获得权限
Set<String> permissions = permissionService.findPermissionByEmployeeId(employee.getId());
//shiro就会自己取进行权限的比较
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
1.3解决undefined
(1)写一个过滤器 覆写PermissionsAuthorizationFilter:
package cn.itsource.aisell.shiro;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AisellPermssionFilter extends PermissionsAuthorizationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
Subject subject = this.getSubject(request, response);
if (subject.getPrincipal() == null) {
this.saveRequestAndRedirectToLogin(request, response);
} else {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//判断请求是否是ajax请求。如果是ajax请求,直接返回json格式
String header = req.getHeader("X-Requested-With");
//说明就是ajax
if(header != null && "XMLHttpRequest".equals(header)){
//返回json格式的数据
resp.setContentType("text/json; charset=UTF-8");
resp.getWriter().print("{\"success\":false,\"msg\":\"没有权限\"}");
}else {
String unauthorizedUrl = this.getUnauthorizedUrl();
if (StringUtils.hasText(unauthorizedUrl)) {
WebUtils.issueRedirect(request, response, unauthorizedUrl);
} else {
WebUtils.toHttp(response).sendError(401);
}
}
}
return false;
}
}
applicationContext-shiro.xm
<!-- 配置自定义过滤器-->
<property name="filters">
<map>
<entry key="aisellPerms" value-ref="aisellPermsFilter">
</entry>
</map>
</property>
<!--自定义过滤器-->
<bean id="aisellPermsFilter" class="cn.itsource.aisell.shiro.AisellPermssionFilter"></bean>
AisellFilterChainDefinitionMap:
map.put(url, "aisellPerms["+permission.getSn()+"]");
1.4.页面权限的控制按钮
<shiro:hasPermission name="employee:delete">
<a href="#" data-method="delete" plain="true" class="easyui-linkbutton" iconCls="icon-remove">删除</a>
</shiro:hasPermission>
2.菜单读取
2.1.Menu
package cn.itsource.aisell.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "menu")
public class Menu extends BaseDomain{
//菜单名字
private String name;
//路径
private String url;
//图标
private String icon;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
@JsonIgnore//忽略json 在展示json格式的 parent不会展示出来
private Menu parent;
//临时属性,不交给jpa管理
@Transient
private List<Menu> children = new ArrayList<>();
//兼容easyui的菜单树
public String getText(){
return this.name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Menu getParent() {
return parent;
}
public void setParent(Menu parent) {
this.parent = parent;
}
public List<Menu> getChildren() {
return children;
}
public void setChildren(List<Menu> children) {
this.children = children;
}
}
Permission:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="menu_id")
private Menu menu;
MenuQuery
public class MenuQuery extends BaseQuery{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Specification createSpecification() {
Specification<Menu> specification = Specifications.<Menu>and()
.like(StringUtils.isNotBlank(this.getName()), "name","%"+this.getName()+"%")
.build();
return specification;
}
}
MenuRepository
public interface MenuRepository extends BaseRepository<Menu,Long>{
//根据用户id 查询菜单--查询所有的子菜单
@Query("select distinct m from Employee e join e.roles er join er.permissions p join p.menu m where e.id = ?1")
List<Menu> findByLoginUser(Long id);
}
IMenuService
public interface IMenuService extends IBaseService<Menu,Long>{
List<Menu> findMenuByLoginUser(Long id);
}
MenuServiceImpl
@Service
public class MenuServiceImpl extends BaseServiceImpl<Menu,Long> implements IMenuService {
@Autowired
private MenuRepository menuRepository;
@Override
public List<Menu> findMenuByLoginUser(Long employeeId) {
List<Menu> menus = new ArrayList<>();
//查询当前用户的所有的子菜单
List<Menu> subMenus = menuRepository.findByLoginUser(employeeId);
for (Menu subMenu : subMenus) {
//从子菜单里面拿到父菜单
Menu parentMenu = subMenu.getParent();
if(!menus.contains(parentMenu)){
menus.add(parentMenu);
}
parentMenu.getChildren().add(subMenu);
}
return menus;
}
}
UtilController
package cn.itsource.aisell.web.controller;
import cn.itsource.aisell.domain.Department;
import cn.itsource.aisell.domain.Employee;
import cn.itsource.aisell.domain.Menu;
import cn.itsource.aisell.service.IDepartmentService;
import cn.itsource.aisell.service.IMenuService;
import cn.itsource.aisell.util.UserContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("/util")
public class UtilController {
@Autowired
private IDepartmentService departmentService;
@Autowired
private IMenuService menuService;
@RequestMapping("/queryDepartment")
@ResponseBody
private List<Department> queryDepartment(){
return departmentService.findAll();
}
@RequestMapping("/findMenuByUserId")
@ResponseBody
public List<Menu> findMenuByUserId(){
//当前用户ID
Employee employee=(Employee) UserContent.getUser();
return menuService.findMenuByLoginUser(employee.getId());
}
}