`

Shiro 安全权限框架整合学习

阅读更多



Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了。对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了。


一、将shiro的依赖包增加到项目pom.xml文件  目前使用的版本是 1.3.2

    <!--shiro包-->

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

 

二、在web.xml文件增加shiro 的监听配置

<!--shiro配置,要放在mvc前面,如果有sitemesh,放在sitemesh前面-->
<filter>
    <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>

 

三、在spring-application.xml 配置文件中引入shiro-config.xml配置文件

<!--shiro权限管理配置 -->
<import  resource="classpath:shiro-config.xml" />

 

shiro-config.xml配置如下:

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd ">

    <!-- web.xml中shiro的filter对应的bean -->
    <!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
         <property name="loginUrl" value="/login" />
        <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
        <property name="successUrl" value="/"/>
        <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
       <property name="unauthorizedUrl" value="/refuse" />
        <property name="filters">
            <map>
                <entry key="authc" value-ref="formAuthenticationFilter" />
                <entry key="logout" value-ref="logoutFilter" />
            </map>
        </property>
        <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
       <property name="filterChainDefinitions">
            <value>
                <!--开发前端库全部开放
                (虽然在容器中用defaultServlet中处理过,但这里是filter,在servlet之前,还是需要指定这些目录不经验证)-->
                 /favicon.ico = anon
                /lib/** = anon
                /js/** = anon
                /css/** = anon
                /img/** = anon
                <!--退出登录接口-->
               /logout = logout
                <!--admin的url必须角色admin才能访问-->
              /admin/** = roles[admin]
                <!--其它url将全部需要登录后才可以访问-->
               /** = authc
            </value>
        </property>
    </bean>

    <bean id="formAuthenticationFilter"
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
        <property name="usernameParam" value="username"/>
        <property name="passwordParam" value="password"/>
        <property name="loginUrl" value="/login"/>
    </bean>

    <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <!-- 退出登录后跳转的页面,默认将跳回登录页面 -->
<property name="redirectUrl" value="/login" />
    </bean>

    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!--
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"/>
    </bean> -->
    <!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="defaultRealm"/>
        <!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
        <!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager" />
    </bean>

    <!-- 默认realm,通过帐号密码进行验证登录 -->
<bean id="defaultRealm" class="com.mywind.eemp.utils.shiro.realm.DefaultRealm">
        <!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
        <!--打开缓存-->
<property name="cachingEnabled" value="true"/>
        <!--把登录信息缓存起来-->
<property name="authenticationCachingEnabled" value="true"/>
        <property name="authenticationCacheName" value="authenticationCache"/>
        <!--把权限信息缓存起来-->
<property name="authorizationCachingEnabled" value="true"/>
        <property name="authorizationCacheName" value="authorizationCache"/>
    </bean>

    <!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <!--使用md5进行密码加密-->
<property name="hashAlgorithmName" value="md5" />
        <!--加密两次-->
<property name="hashIterations" value="2" />
    </bean>


    <!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:permission/shiro-ehcache.xml"/>
    </bean>

    <!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- session的失效时长,单位毫秒 -->
<property name="globalSessionTimeout" value="6000000"/>
        <!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
    </bean>

    <!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie" />
    </bean>

    <!-- 记住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- rememberMe是cookie的名字 -->
<constructor-arg value="rememberMe" />
        <!-- 记住我cookie生效时间30天 -->
<property name="maxAge" value="2592000" />
    </bean>

    <!-- 开启Shiro注解的Spring配置方式的beans。在lifecycleBeanPostProcessor之后运行 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" />
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>


</beans>

 

 

 这里缓存管理使用 了 shiro-ehcache.xml

 

 <?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!--diskStore:缓存数据持久化的目录 地址  -->
<diskStore path="D:/WorkSpace/JAVA/ehcache" />
    <defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

 

 

 四、在shrio-config.xml配置中,自己实现默认的认证授权类。

<bean id="defaultRealm" class="com.mywind.eemp.utils.shiro.realm.DefaultRealm">
DefaultRealm.java 如下:

 

package com.mywind.eemp.utils.shiro.realm;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.mywind.eemp.beans.entity.SysMenuPermission;
import com.mywind.eemp.beans.entity.SysRole;
import com.mywind.eemp.beans.entity.SysUser;
import com.mywind.eemp.enums.SysUserStatusEnum;
import com.mywind.eemp.service.custom.SysRolesPermissionService;
import com.mywind.eemp.service.custom.SysUserRolesService;
import com.mywind.eemp.service.impl.SysUserServiceImpl;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 实现默认的登录认证,和认证通过后的授权方法
 */
public class DefaultRealm extends AuthorizingRealm {

    @Autowired
private SysUserServiceImpl sysUserService;

    @Autowired
private SysUserRolesService sysUserRolesService;

    @Autowired
private SysRolesPermissionService sysRolesPermissionService;


    //认证后的授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SysUser sysUser = (SysUser) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        Set<String> rolesString = new HashSet<>();
        Set<String> permissionString = new HashSet<>();

        //把用户所有的角色查找出来,转化为Set<String>,String为角色名称,并set到AuthorizationInfo中
List<SysRole> roleList = sysUserRolesService.selectRolesBySysUserId(sysUser.getId());

        for (SysRole sysRole : roleList) {
            rolesString.add(sysRole.getMatchString());
        }
        info.setRoles(rolesString);

        //同时把所有这些角色的权限搜索出来,并set到AuthorizationInfo中
List<SysMenuPermission> permissionList = sysRolesPermissionService.selectPermissionsBySysRoles(roleList);
        for (SysMenuPermission sysMenuPermission : permissionList) {
            permissionString.add(sysMenuPermission.getMatchString());
        }
        info.setStringPermissions(permissionString);

        return info;
    }


    //realm的认证方法,从数据库查询用户信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginName = (String) authenticationToken.getPrincipal();

        SysUser sysUser = sysUserService.selectOne(
                new EntityWrapper<SysUser>().eq("login_name", loginName)
        );

        if(sysUser == null) {
            throw new UnknownAccountException(); //没找到帐号
}

        if(sysUser.getIsLock().equals(SysUserStatusEnum.LOCK)) {
            throw new LockedAccountException(); //帐号锁定
}



        //第一个参数建议传SysUser对象进去,后面获取权限的时候可以通过对象获取各种信息,不用去数据库再查一次
SimpleAuthenticationInfo simpleAuthenticationInfo =
                new SimpleAuthenticationInfo(
                        sysUser,
                        sysUser.getPassword(),
                        ByteSource.Util.bytes(sysUser.getSalt()),
                        this.getName()
                );
        return simpleAuthenticationInfo;
    }
}



五、在shrio-config.xml配置文件中filter 指定了登录的入口方法

<property name="loginUrl" value="/login" />

 在controller 的login方法,即可以进行登录认证的结果判定。

 

@Controller
public class LoginController {

    @RequestMapping(value = "/login")
    public String loginPage(HttpServletRequest request, Model model) {
         //如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
        String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
        String error = "";


        //根据shiro返回的异常类路径判断,抛出指定异常信息
        if(exceptionClassName!=null){
            if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
                error = "找不到该用户";
            } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
                error = "用户名/密码错误";
            } else if(LockedAccountException.class.getName().equals(exceptionClassName)){
                error = "你的帐号被锁定了,请稍后再试。";
            } else if(exceptionClassName != null){
                error = "其他错误:" + exceptionClassName;
            }
        }

        model.addAttribute("error", error);
        //这个login方法当登录成功后不做跳转处理,跳转处理已经由shiro来进行处理
        return "login";
    }
}

 

六、shiro权限标签在页面的使用:

      首先导入 权限标签库:<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

    标签:hasPermission 表示拥有某个权限  hasRole 表示拥有某个角色 shiro:user标签表示已经登录的用户属性 

        hasAllRoles表示拥有所有相关的角色;hasAllPermissions表示拥有所有相关的权限;hasAnyPermissions表示拥有任意一个相关的权限。

 
<div class="mywp-header clearfix"><div class="mywp-logo"><h1><a href="">logo</a></h1></div><div class="site-menu"><div class="nav"><div class="overTop"></div><div class="overBottom"></div><a href="#" class="active">首页</a><shiro:hasPermission name="monitor"><a href="#">xx</a></shiro:hasPermission><shiro:hasPermission name="powerAnalysis"><a href="#">综合分析</a></shiro:hasPermission><shiro:hasPermission name="reportManager"><a href="#">报表管理</a></shiro:hasPermission><shiro:hasPermission name="generalSearch"><a href="#">故障告警</a></shiro:hasPermission><shiro:hasRole name="admin"><a href="admin/list">系统配置</a></shiro:hasRole></div><div class="action"><shiro:user>
                <a href="#"><span class="mywp-icon icon-admin"></span>您好,<shiro:principal  property="displayName"/></a>
            </shiro:user> 
</div><div class="exitSystem"><a href="#" id="logout_button"><span class="mywp-icon icon-exit"></span></a></div></div></div>

 

 

 至此,从引入包到配置xml。到实现默认认证和授权,页面标签使用完整可以使用。

 

 

分享到:
评论

相关推荐

    shiro权限框架视频教程共计四套.txt

    第一套shiro企业级权限整合spring 第二套基于springboot权限shiro框架 第三套套shiro基于ssm框架整合 第四套实战简单shiro权限管理系统项目案例实战

    shiro安全权限框架 实战应用技术

    Apache Shiro是一个强大的Java安全框架,它为应用程序提供了身份验证、授权、会话管理和加密服务。本实战应用技术主要关注Shiro如何在实际项目中被有效地利用,通过一系列的示例(dome)来帮助开发者理解和掌握其...

    ssm+shiro权限框架

    SSM+Shiro权限框架是Java Web开发中常用的一种安全控制解决方案,主要结合了Spring、Spring MVC、MyBatis和Apache Shiro四个组件。这个框架提供了全面的权限管理功能,包括用户认证、授权、会话管理和安全性日志等。...

    springboot 与shiro安全框架的整合

    SpringBoot和Shiro是两个在Java开发中广泛使用的框架,SpringBoot简化了Spring应用的初始搭建以及开发过程,而Shiro则是一个强大的安全管理框架,负责处理认证、授权、会话管理和安全相关的过滤器。当我们把它们整合...

    shiro整合ssm框架

    本项目"shiro整合ssm框架"旨在将Shiro与SSM框架集成,提供一套完整的权限验证解决方案。 首先,我们要理解Shiro的核心组件: 1. **Subject**:Shiro的中心概念,代表当前用户的安全视角。 2. **Realm**:用于连接...

    shiro权限框架文档

    Shiro文档通常还会介绍如何通过Shiro的POJO API来进行安全操作,以及如何与Spring Security集成,提供与Spring框架更好的整合性。文档中还可能会介绍Shiro的Grails插件,这是一个专门为Grails框架准备的插件,允许...

    ShiroDemo权限框架处理

    《ShiroDemo权限框架处理详解》 在现代Web开发中,权限管理是不可或缺的一部分,它涉及到用户登录、角色分配、权限控制等多个环节。Apache Shiro作为一款轻量级的安全框架,因其简单易用且功能强大而备受开发者青睐...

    Shiro权限框架文档

    整体而言,文档通过实例介绍了如何在Spring框架中整合Shiro权限框架,给出了Web应用中安全控制的配置方式,包括Shiro过滤器的部署、SecurityManager的配置以及如何实现自定义的Realm来整合用户认证和授权逻辑。...

    SpringBoot整合Shiro权限框架

    SpringBoot整合Shiro权限框架是将SpringBoot与Apache Shiro这两个流行的技术栈结合,用于实现Web应用的安全控制和用户权限管理。SpringBoot以其简洁的配置和快速的开发体验深受开发者喜爱,而Shiro则是一个轻量级的...

    springboot-vue-shiro-权限整合

    springboot+vue+shiro 前后盾分离,权限整合,vue路由配置解析,有sql语句,shiro 权限验证。

    学习 权限框架shiro 的ssm

    以上就是关于"学习权限框架Shiro的SSM"的知识点介绍,通过整合Shiro与SSM,我们可以构建出一套完整的权限管理体系,实现对用户访问的精细控制。在实际项目中,Shiro的灵活性和易用性使得它成为许多开发者首选的安全...

    搭建Springboot整合shiro安全框架+Redis+Swagger+Filter超详细

    在本教程中,我们将深入探讨如何利用Spring Boot整合Shiro安全框架,以实现用户认证与授权,同时结合Redis进行会话管理,以及使用Swagger为API提供文档化接口,最后通过Filter实现自定义的请求处理。以下是对这些...

    shiro安全框架

    Apache Shiro是一个强大的Java安全框架,它为应用程序提供了身份验证、授权、会话管理和加密等核心安全性服务...这个demo项目就是一个很好的起点,它展示了Shiro的基本用法,为开发者提供了实践和学习的安全框架基础。

    Shiro与SSM整合(内含详细文档介绍)

    Apache Shiro 和 Spring Security (SSM) 是两个广泛使用的Java安全框架,它们分别提供认证、授权、会话管理和加密等功能,以确保Web应用程序的安全性。本资料包将深入讲解如何将Shiro与SSM整合,以实现更高效、灵活...

    Shiro权限框架深入浅出.pdf

    Apache Shiro是一个开源的Java安全框架,其核心功能是权限管理,常常被拿来与Spring Security框架进行对比。Shiro的特点在于其简单易用,它提供了认证(Authentication)、授权(Authorization)、会话管理(Session...

    shiro权限框架资料.zip

    shiro 权限框架学习资料, 从最基本的maven 工程到springboot 的整合, 再到一个通用的RBAC 权限框架模板的设计与创作, 包括视频, 源码, 资料, 稳定, 笔记, 软件, 依赖等等

    Maven+SSM+Shiro框架整合完整实现,实现某权限用户登录,记住密码,验证码等功能。

    在本项目中,"Maven+SSM+Shiro框架整合完整实现"旨在提供一个完整的解决方案,包括用户登录、记住密码、验证码等常见功能,并且可以方便地导入MySQL数据库进行运行。 **Maven** 是一个项目管理和综合工具,它帮助...

    maven+SpringMvc+Mybatis+shiro安全框架整合实例(-)

    整合这些框架,开发者可以构建出一个具备完整功能的Web应用:Maven管理依赖,SpringMVC处理请求,MyBatis执行数据库操作,而Shiro则负责安全保障。这样的组合不仅提高了开发效率,也使得系统更加模块化和易于维护。...

    JFinal2.0整合shiro权限框架,简单好用

    **JFinal2.0整合Apache Shiro权限框架详解** JFinal是一个基于Java的高效、轻量级的Web开发框架,它的设计目标是让开发者能够快速地进行开发,减少了大量重复的代码工作。Apache Shiro则是一款强大的安全管理框架,...

    shiro框架整合(全包)

    总的来说,"shiro框架整合(全包)"提供了构建安全应用所需的一切,从基础的认证和授权,到高级的缓存配置和Spring集成,是开发者快速上手Shiro并实现安全功能的理想资源。通过这个压缩包,你可以便捷地在项目中集成...

Global site tag (gtag.js) - Google Analytics