Shiro安全框架

Shiro部署

导入依赖

<!--shiro安全控制框架-->
			<dependency>
				<groupId>commons-collections</groupId>
				<artifactId>commons-collections</artifactId>
				<version>3.2.1</version>
			</dependency>

			<dependency>
				<groupId>net.sf.ehcache</groupId>
				<artifactId>ehcache-core</artifactId>
				<version>2.6.9</version>
			</dependency>

			<dependency>
				<groupId>org.apache.shiro</groupId>
				<artifactId>shiro-spring</artifactId>
				<version>1.2.3</version>
			</dependency>

			<dependency>
				<groupId>org.apache.shiro</groupId>
				<artifactId>shiro-ehcache</artifactId>
				<version>1.2.3</version>
			</dependency>

			<dependency>
				<groupId>org.apache.shiro</groupId>
				<artifactId>shiro-quartz</artifactId>
				<version>1.2.3</version>
			</dependency>

配置web.xml文件

  • 让所有的请求都先经过shiro的验证
    在这里插入图片描述

需要的配置文件
在这里插入图片描述

主配置文件

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

    <!-- 如果在service上想使用权限注解,需要在这里也加上此段配置(spring-mvc虽然也配置了此段,但那只对controller有效) -->
    
    <aop:config proxy-target-class="true"></aop:config>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

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

    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>

    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="sid"/>
        <property name="httpOnly" value="true"/>
        <property name="maxAge" value="180000"/>
    </bean>

    <!-- 会话DAO -->
    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>

    <!-- 会话验证调度器 -->
    <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
        <property name="sessionValidationInterval" value="1800000"/>
        <property name="sessionManager" ref="sessionManager"/>
    </bean>
    <!-- <bean id="sessionValidationScheduler" class="com.study.it.shiro.Quartz2SessionValidationScheduler">&lt;!&ndash; 适应quartz的高版本 ,自己扩充的类&ndash;&gt;
         <property name="sessionValidationInterval" value="1800000"/>
         <property name="sessionManager" ref="sessionManager"/>
     </bean>-->

    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="globalSessionTimeout" value="1800000"/>
        <property name="deleteInvalidSessions" value="true"/>
        <property name="sessionValidationSchedulerEnabled" value="true"/>
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
        <property name="sessionDAO" ref="sessionDAO"/>
        <property name="sessionIdCookieEnabled" value="true"/>
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm"/>
        <property name="sessionManager" ref="sessionManager"/>
        <property name="cacheManager" ref="cacheManager"/>
        <property name="rememberMeManager" ref="rememberMeManager"/><!-- rememberMe -->
    </bean>

    <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
        <property name="arguments" ref="securityManager"/>
    </bean>

    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"><!-- rememberMe -->
        <constructor-arg value="rememberMe"/>
        <property name="httpOnly" value="true"/>
        <property name="maxAge" value="2592000"/><!-- 30-->
    </bean>

    <!-- rememberMe管理器 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"><!-- rememberMe -->
        <!-- rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)-->
        <property name="cipherKey"
                  value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/>
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>

    <!-- 基于Form表单的身份验证过滤器 -->
    <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"/>
        <property name="rememberMeParam" value="rememberMe"/><!-- rememberMe -->
        <property name="failureKeyAttribute" value="shiroLoginFailure"></property>
    </bean>

    <!-- 凭证匹配器 -->
    <bean id="credentialsMatcher" class="com.ysl.shiro.MyCredentialsMatcher"/><!-- 验证密码的子类 -->

    <!-- Realm实现 -->
    <bean id="userRealm" class="com.ysl.shiro.MyUserRealm" p:empService-ref="empService"><!-- 验证用户名 和加载拥有什么权限 的类-->
        <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="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/login"/><!-- 指定注销后跳转到哪里 -->
    </bean>
    <!-- Shiro的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login"/><!--登录的网址  -->
        <property name="successUrl" value="/checkin"/><!-- 如果没有旧url的情况下,登录成功跳转到哪里 -->
        <property name="unauthorizedUrl" value="/toDeny"/><!--无权限的时候跳转到哪里  -->
        <property name="filters">
            <map>
                <entry key="authc" value-ref="formAuthenticationFilter"/><!-- 登录的时候经过的过滤器 -->
                <entry key="logout" value-ref="logoutFilter"/><!-- 注销的时候经过的过滤器 -->
            </map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** = anon
                /imgs/** = anon

                /login = authc
                /logout = logout
                /abc/* = user

            </value>
        </property>
    </bean>

    <!-- Shiro生命周期处理器-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

</beans>

缓存配置文件
在这里插入图片描述

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

    <diskStore path="java.io.tmpdir"/>

    <!-- 登录记录缓存 锁定10分钟 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-activeSessionCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

在这里插入图片描述在这里插入图片描述

Controller类

认证和授权
在这里插入图片描述

登录验证的代码

package com.ysl.shiro;

import com.ysl.bean.Emp;
import com.ysl.service.EmpService;
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.subject.PrincipalCollection;

public class MyUserRealm extends AuthorizingRealm {

    private EmpService empService;

    public void setEmpService(EmpService empService) {
        this.empService = empService;
    }

    /**
     * 授权(访问控制)
     * <p>
     * 加载当前用户到底有哪些权限和角色
     *
     * 想办法加载用户权限
     * 数据库/xml/第三方
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //在当前参数中提取当前的登录用户信息
        Emp emp = (Emp) principalCollection.getPrimaryPrincipal();

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //加载角色
        if (emp.getRole() != null) {

            //按","分割角色,获取角色的数组
            String[] roleArray = emp.getRole().split(",");

            for (String role : roleArray) {
                System.out.println("角色为" + role);
                //封装所有的角色信息
                info.addRole(role);
            }
        }

        if (emp.getPermiss() != null) {

            //按","分割权限,获取权限的数组
            String[] pArray = emp.getPermiss().split(",");

            for (String p : pArray) {
                System.out.println("权限为" + p);
                //封装所有的权限信息
                info.addStringPermission(p);
            }
        }

        return info;
    }


    /**
     * 认证(登录)
     * <p>
     * 查询数据库
     * 比对用户名
     * 读取用户信息
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获取用户名
        String username = token.getPrincipal().toString();

        //根据用户名查询用户是否存在
        //只验证用户名
        Emp emp = empService.findByEmpName(username);

        if (emp == null) {
            throw new UnknownAccountException("无此账号用户");
        }
        System.out.println(emp);

        //制作凭证用于下一步的密码验证
        // 参数
        // 1-是主要凭证,为了有更多的数据可用,我们压入user对象,要标记为可序列化(排除不必要的字段);
        // 2-数据库记录的密码是多少;
        // 3-本类的名称
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(emp, emp.getPwd(), emp.getName());

        return info;
    }
}

在这里插入图片描述
在这里插入图片描述

密码匹配器
在这里插入图片描述

package com.ysl.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;

/**
 * 密码匹配器
 *
 * 需要通过配置文件注册到框架中
 *
 * @program: Day0724_Shiro
 * @description
 * @author: YS_LAR
 * @create: 2021-07-24 15:33
 **/
public class MyCredentialsMatcher implements CredentialsMatcher {
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

        //界面录入的密码
        String input = new String((char[]) token.getCredentials());

        //从数据库中获得的密码
        String stand = info.getCredentials().toString();

        //匹配密码
        //返回true或false
        return stand.equalsIgnoreCase(input);
    }
}

在这里插入图片描述

Service层

在这里插入图片描述
Realm实现配置
在这里插入图片描述
在这里插入图片描述
Service实现
在这里插入图片描述

Dao层

在这里插入图片描述
Dao层xml文件编写
在这里插入图片描述

配置

在这里插入图片描述
Form表单登录数据获取配置
在这里插入图片描述
在这里插入图片描述

登录

在这里插入图片描述

在配置文件配置登录路径
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置mvc.xml
在这里插入图片描述

配置注销后跳转
在这里插入图片描述
访问控制
在这里插入图片描述
使用注解判断权限
在这里插入图片描述
管理员和经理的权限不同在这里插入图片描述

在这里插入图片描述
两种角色和权限放在同一url下,需要进一步判断权限
在这里插入图片描述
分解成两个方法
在这里插入图片描述

JSP页面

导入shiro标识
在这里插入图片描述
取值
在这里插入图片描述
JSP也可以进行Shiro权限判断
在这里插入图片描述

异常处理

在这里插入图片描述

在这里插入图片描述
考虑ajax情况下的异常
在这里插入图片描述
发生异常跳转到登录页

  • 错误页提供登录手段
  • 在shiro主配置文件中增加配置
    在这里插入图片描述
    在这里插入图片描述

shiro配置文件属性

在这里插入图片描述

Shiro注解说明

在这里插入图片描述

JSP的Shiro标识

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值