Landing permission settings based on permission settings menu

1. In the project add permissions

shiro processing authority process:

(1) all the rights to shiro management --createFilterChainDefinitionMap may reflect treatment

(2) will query the current user's privileges in the realm inside, authority if the authority in the management shiro return, the user will have this response

Otherwise there is no

1.1 All permissions from the database query to pay a management shiro

 // 从数据库啊查询到所有的权限 交给shiro管理
        List<Permission> all = iPermissionService.findAll();
        for (Permission Permission : all) {
            // 权限对应的资源请求地址
            String url = Permission.getUrl();
            //权限
            String sn = Permission.getSn();
        // 放进map交给shiro管理  aisellPerms去找我们自己写的自定义的过滤器  Perms默认值找的是shiro的过滤器我们继承复写后需要改成我们自己的
            mp.put(url, "aisellPerms[" + sn + "]");
        }

How to reflect the map inside shiro authority to manage it:
Configure custom permissions filter

        自定义权限过滤必须有  使用自定义的权限过滤器必须有工厂bena的支持才能使用 
            

 <!-- 真实的过滤器处理 id这个名字 必须和web.xml里面配置的代理的过滤器的名称一样,才行-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"></property>

        <!-- 如果没有认证,会跳转该页面-->
        <property name="loginUrl" value="/login"></property>
        <!--认证成功,跳转的页面-->
        <property name="successUrl" value="/main"></property>
        <!--没有权限-->
        <property name="unauthorizedUrl" value="/s/unauthorized.jsp"></property>

        <!--配置自定义过滤器-->
<property name="filters">
    <map>
        <entry key="aisellPerms" value-ref="aisellPermsFilter">
        </entry>
    </map>
</property>
        <!--拦截配置-->
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap1"></property>
    </bean>


    <!-- 定义自定义过滤器-->
    <bean id="aisellPermsFilter"
          class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMapBuilder"></bean>
    <!-- 配置两个bean   引用map这个类 就动态的拿到了每个用户的权限-->
    <bean id="filterChainDefinitionMap1" factory-bean="filterMapFactoyBean" factory-method="createFilterChainDefinitionMap">
    </bean>
   <!--   引用map这个类 就动态的拿到了每个用户的权限就能进行拦截和放行-->
    <bean id="filterMapFactoyBean" class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMap"></bean>
 



1.2 queries the current user has permissions

--sql语句查询当前用户的权限
select p.* from employee e
join employee_role er on e.id = er.employee_id
join role r on er.role_id = r.id
join role_permission rp on rp.role_id = r.id
join permission p on p.id = rp.permission_id 
where e.id = 2

  jpql查询语句
  @Query("select p.sn from Employee e join e.roles er join er.permissions p where e.id = ?1 ")
    public Set<String> findPermissionsByLoginUser(Long id);

  当你前台登录后就会将登陆对象传到后台来验证  验证结束后进入如此方法授权
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //授权方法
        Employee employee =(Employee) principalCollection.getPrimaryPrincipal();
      /*根据用户名得到权限代码
        从数据库查询当前用户的所有的权限
       三层架构通过用户id去查询 用户权限 连表查寻*/
       // Set<String> permissions = getPermissionsByUsername(employee.getUsername());
        Set<String> permissionSet = permissionService.findPermissionByEmployeeId(employee.getId());
        //shiro就会自己取进行权限的比较
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setStringPermissions(permissionSet);
        return authorizationInfo;
    }

After 1.3 permissions problems, ajax how to return

Why is there this underlying problem shiro will not process your request so ajax ajax request if you send enough authority Undefined box will pop up (the prompt does not meet our requirements)
solution:

(1) Write a filter override PermissionsAuthorizationFilter

(2) Method override onAccessDenied

The method determines if there is a request to return directly ajax json format,

Otherwise, go to the original format, return to the page

     public class AisellFilterChainDefinitionMapBuilder extends PermissionsAuthorizationFilter {
    //没有权限的时候 返回的方法
    /**
     *  判断请求是否是ajax请求。如果是ajax请求,直接返回json格式
     *  否则走它以前的返回页面的代码
     *   就是一个自定义的拦截器的类
   */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        // 通过请求拿到主体对象
        Subject subject = this.getSubject(request, response);
       // System.out.println(subject.getPrincipal());
        //  得到的用户若是为空则表示没有登录
        if (subject.getPrincipal()==null){
           //没有登录成功后的操作
            this.saveRequestAndRedirectToLogin(request, response);
        }else {
           // 强转为子类方法多啊
            HttpServletRequest req=  (HttpServletRequest)request;
            HttpServletResponse resp=(HttpServletResponse) response;
            // 判断是否使ajax请求该方法会得到一个返回值     若是ajax请求的话再请求头里面会有这个key属性呢 X-Requested-With
            String header = req.getHeader("X-Requested-With");

             // 判断返回的是否是ajax的请求 XMLHttpRequest 是ajax请求的value
             if (header!=null && "XMLHttpRequest".equals(header)){
                  // 说明就是ajax请求 返回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;
    }

}

The arrangement defined filters to the inside applicationcontext-shiro.xml

        <!--配置自定义过滤器-->
<property name="filters">
    <map>
        <entry key="aisellPerms" value-ref="aisellPermsFilter">
        </entry>
    </map>
<!-- 定义自定义过滤器-->
    <bean id="aisellPermsFilter"
          class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMapBuilder"></bean>

Once configured, the time needed to find again a transmission request custom filter: See map configuration inside

1.4 page button control authority

Add tags to control page button is displayed shiro will pass this tag to determine whether they have permission

  //  引入标签库支持
 <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>


 <shiro:hasPermission name="employee:delete">
             <a href="#" data-method="delete" plain="true"   class="easyui-linkbutton" iconCls="icon-remove">删除</a>
  </shiro:hasPermission>

2 tree menu on the left

Demand: Dynamic Gets the menu displays a menu based on user rights

OK 2.1 menu object

Wrote Menu domain objects

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;

    @Transient //这个是临时属性,不交给jpa管理 ,自己来维护 -- 手动添加子菜单
    private List<Menu> children = new ArrayList();

    //兼容esayui的菜单树[id:1,text:'xxx'] esayui的格式是text
    public String getText(){
        return this.name;
    }
    //setget...
    }

2.2 service configuration method json

public List<Menu> findMenuByLoginUser(Long employeeId) {
        List<Menu> menus = new ArrayList();
        //查询当前用户的所有的子菜单
        List<Menu> subMenus = menuRepository.findByLoginUser(employeeId);
        //循环子菜单  2,3,4,5    1   (7 8)  6
        for (Menu subMenu : subMenus) {
            //从子菜单里面拿到父菜单 6
            Menu parentMenu = subMenu.getParent();
            // 判断集合里面是否有这个对象
            if(!menus.contains(parentMenu)) {
            //若是没有则添加一个
                menus.add(parentMenu);
            }
            //通过父菜单查询出子菜单 放到对象里面去
            parentMenu.getChildren().add(subMenu);//[1,[2,3,4,5],6 [7,8]]
        }

        return menus;
    }
Published 23 original articles · won praise 2 · Views 934

Guess you like

Origin blog.csdn.net/metjoyful/article/details/102508615