shiro权限项目中的简单应用

Posted @路痴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro权限项目中的简单应用相关的知识,希望对你有一定的参考价值。

SpringMVC+maven

项目需要使用shiro,所以自学了几天,仅提供给新手,请根据文档查看…该项目仅是测试项目,并不完善,只实现了需要使用的基本功能,并且只提供了使用shiro模块的代码。楼主新人第一次写,如有问题希望能提出来,由衷的感谢。


首先是pom.xml:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.2.0</version>
</dependency>

以下是web.xml配置:

<filter>
    <!-- filter-name需要和shiro的过滤器id一致 -->
    <filter-name>shiroFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

以下是shiro的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="   
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd   
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- shior配置 begin -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- <property name="cacheManager" ref="cacheManager" /> -->
        <!-- 自定义的Realm -->
        <property name="realm" ref="myRealm" />
    </bean>

    <!-- 缓存 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    </bean>

    <bean id="myRealm"
        class="com.renai.shop.service.admin.AuthenticationRealm">
        <!-- 加密 -->
        <!-- <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> 
            <property name="hashAlgorithmName" value="SHA-256"/> <property name="storedCredentialsHexEncoded" 
            value="false"/> </bean> </property> -->
    </bean>

    <!-- SecurityManager是shiro的核心,协调shiro的各个组件 -->
    <bean
        class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

    <!-- shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login/gotoLogin.html" />
        <property name="unauthorizedUrl" value="/unauthorized.jsp" />
        <property name="filterChainDefinitions">
            <value>
                /login/gotoLogin.html = anon
                /login/login.html = anon
                /login/** = authc
                /sys/** = authc
                <!-- /sys/add/** = authc, roles[manager]
                /sys/update/** = authc, roles[admin]
                /sys/delete/** = authc, perms[delete] -->
            </value>
        </property>
    </bean>

</beans>  

以下是自定义的Realm类:

package com.renai.shop.service.admin;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.renai.shop.dao.mapper.SysDictionaryMapper;
import com.renai.shop.model.admin.AdmPermission;
import com.renai.shop.model.admin.AdmRole;
import com.renai.shop.model.admin.AdmUserInfo;

/**
 * @作者 zjm
 * @类说明:
 * @创建日期 2015年03月19日
 * @版本 V 1.0
 */
public class AuthenticationRealm extends AuthorizingRealm 

    @Autowired
    private SysDictionaryMapper sysDictionaryMapper;

    /**
     * 给权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)  throws AuthenticationException

        System.out.println("--------------------------doGetAuthorizationInfo--------------------------");

        //获取用户名
        String userName = (String) getAvailablePrincipal(principals);
        SimpleAuthorizationInfo info = null;

        if (StringUtils.isNotBlank(userName)) 
            //按照用户名查询
            AdmUserInfo userInfo = sysDictionaryMapper.getUserInfoByUserName(userName);

            if (userInfo != null) 
                //获取用户的角色,并保存,过滤角色时使用
                List<AdmRole> roles = userInfo.getRoles();
                Set<String> roleNames = new HashSet<String>(); 
                Set<String> permissions = new HashSet<String>(); 
                for (AdmRole role : roles) 
                    roleNames.add(role.getName());
                    //获取角色的权限,并保存,过滤权限时使用
                    for (AdmPermission permission : role.getPermissions()) 
                        permissions.add(permission.getOperation());
                    
                
                //保存角色和权限
                info = new SimpleAuthorizationInfo(roleNames);
                info.setStringPermissions(permissions);
            

         else 
            System.out.println("--------------------------用户名不能为空!--------------------------");
        

        return info;
    

    /**
     * 登陆验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException 

        System.out.println("--------------------------doGetAuthenticationInfo--------------------------");

        //获取登录用户的信息
        UsernamePasswordToken upToken = (UsernamePasswordToken)token;
        SimpleAuthenticationInfo info = null;
        String userName = upToken.getUsername();
        String passWord = String.valueOf(upToken.getPassword());

        AdmUserInfo userInfo = sysDictionaryMapper.login(userName, passWord);
        if (userInfo == null) 
            //抛出的异常在LoginController中处理
            throw new UnknownAccountException("用户名或密码错误");
        

        try 
            info = new SimpleAuthenticationInfo(userName, passWord, getName());
         catch (Exception e) 
            throw new AuthenticationException("验证失败", e);
        
        return info;
    

登录Controller:

package com.renai.shop.admin.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.renai.shop.filter.admin.AdmMenuFilter;
import com.renai.shop.model.admin.AdmMenu;
import com.renai.shop.model.admin.AdmUserInfo;
import com.renai.shop.service.admin.api.ISysDictionaryService;

/**
 * @作者 zjm
 * @类说明:
 * @创建日期 2015年03月19日
 * @版本 V 1.0
 */
@RequestMapping(value = "/login")
@Controller
public class LoginController 

    @Autowired
    private ISysDictionaryService sysDictionaryService;

    @RequestMapping(value = "/gotoLogin.html")
    public String goToLogin(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap) 

        return "login";
    

    @RequestMapping(value = "/login.html")
    @ResponseBody
    public String login(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap,
            @Param(value = "username") String username,
            @Param(value = "password") String password) 

        UsernamePasswordToken token = new UsernamePasswordToken(username,
                password);

        Subject subject = SecurityUtils.getSubject();
        try 
            //调用AuthenticationRealm的doGetAuthenticationInfo
            subject.login(token);
         catch (UnknownAccountException ex) 
            System.out.println("用户名没有找到" + ex.toString());
            return "error";
         catch (IncorrectCredentialsException ex) 
            System.out.println("用户名密码不匹配" + ex.toString());
            return "error";
         catch (AuthenticationException e) 
            System.out.println("其他的登录错误" + e.toString());
            return "error";
         catch (Exception e) 
            System.out.println("登陆失败" + e.toString());
            return "error";
        
        // 记住令牌
        token.setRememberMe(true);

        return "success";
    

    @RequestMapping(value = "/goToIndex.html")
    public String goToIndex(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap) 

        Subject subject = SecurityUtils.getSubject();

        String userName = subject.getPrincipal().toString();
        if (StringUtils.isNotBlank(userName)) 
            AdmUserInfo userInfo = sysDictionaryService.getUserInfoByUserName(userName);
            if (userInfo != null ) 
                AdmMenuFilter filter = new AdmMenuFilter();
                filter.setMenuType(1);

                if (userInfo.getRoles().size() > 0) 
                    //按照角色获取用户的菜单
                    List<AdmMenu> menuList = sysDictionaryService
                            .selectMenuByRolesId(userInfo.getAdmUserRoleInfos(), filter);
                    request.getSession().setAttribute("menuList", menuList);
                
            
        

        return "index";
    

    @RequestMapping(value = "/goToDefault.html")
    public String goToDefault(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap) 
        return "default";
    

    @RequestMapping(value = "/logout.html")
    public String logout(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap) 
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "login";
    

系统Controller:

package com.renai.shop.admin.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.renai.shop.filter.admin.AdmMenuFilter;
import com.renai.shop.model.admin.AdmMenu;
import com.renai.shop.model.admin.AdmUserInfo;
import com.renai.shop.service.admin.api.ISysDictionaryService;

/**
 * @作者 zjm
 * @类说明:
 * @创建日期 2015年03月19日
 * @版本 V 1.0
 */
@RequestMapping(value = "/sys")
@Controller
public class SysController 

    @Autowired
    private ISysDictionaryService sysDictionaryService;

    @RequestMapping(value = "/getMenuByParent.html")
    public String getMenuByParent(HttpServletRequest request,
            HttpServletResponse response, ModelMap modelMap,
            @Param(value = "parentId") int parentId) 

        Subject subject = SecurityUtils.getSubject();

        String userName = subject.getPrincipal().toString();
        if (StringUtils.isNotBlank(userName)) 
            AdmUserInfo userInfo = sysDictionaryService.getUserInfoByUserName(userName);

            if (userInfo != null) 

                AdmMenuFilter filter = new AdmMenuFilter();
                filter.setMenuType(2);
                filter.setParentId(parentId);

                // 查询权限
                if (userInfo.getRoles().size() > 0) 
                    List<AdmMenu> thirdMenuList = sysDictionaryService
                            .selectMenuByRolesId(userInfo.getAdmUserRoleInfos(), filter);
                    request.getSession().setAttribute("thirdMenuList", thirdMenuList);
                
            
        
        return "ajax/ajaxGetMenu";
    



以下是页面:
使用shiro的标签需要引用:

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

以下是按照登录时保存的权限显示按钮

<div class="tools">
    <ul class="toolbar">
        <shiro:hasPermission name="add">
            <li class="click" onclick="add()"><span><img
                    src="$ctx/skin/images/t01.png"></span>添加</li>
        </shiro:hasPermission>
        <shiro:hasPermission name="update">
            <li class="click" onclick="update()"><span><img
                    src="$ctx/skin/images/t02.png"></span>修改</li>
        </shiro:hasPermission>
        <shiro:hasPermission name="delete">
            <li onclick="deletes()"><span><img
                    src="$ctx/skin/images/t03.png"></span>删除</li>
        </shiro:hasPermission>
    </ul>
</div>

以下是项目数据


菜单表

角色表

权限表

以下是项目页面部分截图
第一个是“boos”角色登陆

第二个是“manager”角色登陆

第三个是“admin”角色登陆

以上是关于shiro权限项目中的简单应用的主要内容,如果未能解决你的问题,请参考以下文章

在 Web 项目中应用 Apache Shiro

springboot整合shiro应用

shiro不重启动态加载权限

(转) shiro权限框架详解06-shiro与web项目整合(上)

十 Spring Boot Shiro 权限管理

Shiro + JWT权限验证