shiro权限框架与spring的集成

本文介绍Apache Shiro权限框架的核心概念及使用方法,包括四大基石、架构组成、集成Spring过程及自定义Realm实现。

shiro是一个强大且易用的Java权限的框架

  1. shiro有四大基石
    ①身份验证—登陆
    ②授权:权限判断
    ③密码学:加密
    ④会话管理:session
  2. shiro的架构
    ①subject:当前用户
    ②SecurityManager:shiro的权限管理器—核心对象
    ③realm:shiro从中获取数据
  3. 如何使用shiro
    首先需要导入shiro的jar包
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>日志包
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
  1. 代码步骤

        //需要先获取SecurityManager对象,通过工厂对象IniSecurityManagerFactory
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        //把SecurityManager对象设置到上下文,让所有地方都可调用
        SecurityUtils.setSecurityManager(securityManager);
        //获取当前用户或者是游客
        Subject subject = SecurityUtils.getSubject();
        //判断是否登陆,没有登陆就让他登陆
        if (!subject.isAuthenticated()){
            try {
            //要登陆,先准备令牌,传入用户名和密码
            UsernamePasswordToken token = new UsernamePasswordToken("root","92597");
            //登陆
            subject.login(token);
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("用户名出错!!!");
                //Incorrect(错误的)Credentials(凭证)Exception
            }catch (IncorrectCredentialsException e) {
                e.printStackTrace();
                System.out.println("密码出错!!!");
            }catch (AuthenticationException e){
                e.printStackTrace();
                System.out.println("出现了一个神密的错误!!!");
            }
        }
        //是否登陆
        System.out.println("是否登陆"+subject.isAuthenticated());
        //角色判断
        System.out.println("admin角色"+subject.hasRole("admin"));
        //权限判断
        System.out.println("有employee的权限"+subject.isPermitted("employee:save"));
        //退出登陆
//        subject.logout();
   
  1. 自定义realm —直接继承AuthorizingRealm,继承这个类后实现两个方法,
    doGetAuthorizationInfo(授权) /doGetAuthenticationInfo(登录认证)
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //拿到Token ---只有这一个UsernamePasswordToken令牌,所以可以强转
    UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
    //通过token拿到用户名 ---登陆时输入的用户名
    String username = token.getUsername();
    //通过用户名拿到数据库中的密码
    String password = getByName(username);
    if (password==null){
        //返回空就是代表用户名不存在,shior会自动帮你报UnknownAccountException
        return null;
    }
    //将前台传入的用户名,和数据库中的密码传入,SimpleAuthenticationInfo会自动帮我们判断是否正确---realmName:"名称随便取"
    SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password,"MyRealm");
    return simpleAuthenticationInfo;
}
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    //拿到当前用户名
    String username = (String)principalCollection.getPrimaryPrincipal();
    //根据用户名拿到对应角色与权限
    Set<String> roles = getRolesByUsername(username);
    Set<String> permissions = getPermissionsByUsername(username);
    //拿到验证信息对象
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    //设置角色
    simpleAuthorizationInfo.setRoles(roles);
    //设置权限
    simpleAuthorizationInfo.setStringPermissions(permissions);
    return simpleAuthorizationInfo;
}
  1. 密码加密
/**
 *第一个参数是加密算法:MD5
 *第二个参数是原始密码:admin
 *第三个参数是盐值:zbj
 *第四个参数是加密次数:6
 */
SimpleHash simpleHash = new SimpleHash("MD5","admin","zbj",6);
  1. 如果密码是加密之后的,那么在登陆判断时,也需要使用md5加密方式判断
    ①测试方法中,让自定义realm加上算法
//使用MD5加密方式判断密码
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//密码匹配器
//设置加密方式
matcher.setHashAlgorithmName("md5");
//设置加密次数
matcher.setHashIterations(6);
//将匹配器交给realm
myRealm.setCredentialsMatcher(matcher);

②盐值判断需要在登陆验证方法中添加盐值

//加密验证的加盐
//准备盐值
ByteSource bytes = ByteSource.Util.bytes("zbj");
SimpleAuthenticationInfo simpleAuthenticationInfo = new                                                   SimpleAuthenticationInfo(username,password,bytes,"MyRealm");

shiro集成spring

  1. 导包
<!-- shiro的支持包 -->
 <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-all</artifactId>
    <version>1.4.0</version>
    <type>pom</type>
</dependency>
  <!-- shiro与Spring的集成包 -->
  <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
  </dependency>

  1. 在web.xml中配置shiro的过滤器
    这个过滤器并没有什么实际意义,真正的过滤器在spring的xml配置文件中,但是两个过滤器的名字必须相同
<!--shiro的过滤器,并没有什么作用,真正的过滤器在applicationContext-shiro.xml中-->
<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>
  1. (3)配置applicationContext-shiro.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"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!--shiro的核心对象 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="aiSellRealm"/>
    </bean>
    <!--自定义的一个Realm-->
    <bean id="aiSellRealm" class="cn.zr.aisell.shiro.AiSellRealm">
        <property name="credentialsMatcher">
            <!--hash散列 ,MD5加密 -->
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <property name="hashAlgorithmName" value="MD5"/>
                <property name="hashIterations" value="6"/>
            </bean>
        </property>
    </bean>
    <!--shiro的注解支持-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.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>
    <!--真正的过滤器-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--没有登陆,跳转到这个路径-->
        <property name="loginUrl" value="/login"/>
        <!--登陆成功,跳转到这个路径-->
        <property name="successUrl" value="/main"/>
        <!--没有权限,跳转到这个路径-->
        <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionMapFactory">
        </property>
    </bean>
    <bean id="filterChainDefinitionMapFactory" factory-bean="filterChainDefinitionMap" factory-method="createFilterChainDefinitionMap"/>
    <bean id="filterChainDefinitionMap" class="cn.zr.aisell.shiro.FilterChainDefinitionMapBuilder"/>

</beans>
  1. 在核心配置文件applicationContext.xml中配置读取applicationContext-shiro.xml
<import resource="classpath:applicationContext-shiro.xml" />
  1. 把路径权限放入map集合中,并且是有序的map集合
    新建一个类,并且这个类已经在shiro.xml中配置了bean,这样放行路径和权限路径就是动态的了
//LinkedHashMap是有顺序的
Map<String , String> map = new LinkedHashMap<>();
//存入路径与是否可以访问
//这个是放行路径
map.put("/s/login.jsp","anon");
map.put("/login","anon");
//放行easyui,js的样式
map.put("/easyui/**","anon");
map.put("/js/**","anon");
map.put("/images/**","anon");
map.put("/css/**","anon");
map.put("/fonts/**","anon");
//需要只有相应的权限才能访问的路径
map.put("/employee/index","perms[employee:index]");
//必须登陆才能访问的路径
map.put("/**","authc");
return map;
乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值