Spring-Shiro整合

因为web项目的核心组件(Service,dao)都在spring工厂中管理,利用IOC和AOP,组建了关系松散,稳健的系统。
shiro的诸多组件也需要由spring统一管理,进而可以更好的和其他组件协作,因为shiro中大多数组件都是pojo类,更方便管理我们可以很方便地把它们从shiro.ini中迁到Spring工厂中。
pom文件

<!-- 其他依赖和web集成中 一致 ,此处省略-->
<!-- 新增一个依赖 用于在工厂中生产 ShiroFilter-->
<!-- 会传递导入shiro-core 和 shiro-web -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>

applicationContext_shiro.xml配置文件
将shiro的三大核心组件SecurityMnager,Subject,Realm,放到配置文件,这里我们可以将shiro单独放到一个配置文件中,在Spring的配置文件中导入该配置文件即可。

    <!-- shiro配置 -->
   <!--注入自定义realm组件-->
    <bean id="myRealm" class="com.lsw.realm.MyRealm">
        <property name="userService" ref="userServiceImpl"/>
        <property name="roleService" ref="roleServiceImpl"/>
        <property name="permissionService" ref="permissionServiceImpl"/>

   <!--配置密码对比器  登陆时realm会根据盐迭代次数以及加密算法  来得出用户信息来对比数据库中的用户信息  进行身份验证-->
        <property name="credentialsMatcher">
          <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
              <!--声明迭代次数-->
              <property name="hashIterations" value="10000"/>
              <!--声明加密算法-->
              <property name="hashAlgorithmName" value="SHA-256"/>
              <!--声true=hex格式  false=base64格式明-->
              <property name="storedCredentialsHexEncoded" value="false"/>
          </bean>
        </property>
    </bean>

    <!--注入安全管理器securityManager-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--将realm注入-->
       <property name="realm" ref="myRealm"/>
        <!--将rememberMeManager注入-->
        <property name="rememberMeManager" ref="rememberMeManager"/>
        <!--注入session管理器-->
        <property name="sessionManager" ref="sessionManager"/>
    </bean>

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!--注入核心组件-->
        <property name="securityManager" ref="securityManager"/>
        <!--声明未登录   没权限的-->
        <property name="loginUrl" value="/user/login"/>
        <property name="unauthorizedUrl" value="/user/error"/>
<!--过滤器链   这里后面可以用注解代替 -->
        <property name="filterChainDefinitions">
            <value>
            /user/login = anon
            /user/login = anon
            /user/all = authc,roles["admin"]
            /user/update = authc,roles["manager","seller"]
            /user/delete = authc, perms["user:update","user:delete"]
            /user/logout = logout
            </value>
        </property>
    </bean>

    <!--自定义记住我-->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- cookie的生命周期,单位:秒    7天-->
        <property name="maxAge" value="2592000"/>
        <property name="name" value="rememberMe"/>
        <!-- cookie只在http请求中可用,那么通过js脚本将无法读取到cookie信息,有效防止cookie被窃取 -->
        <property name="httpOnly" value="true"/>
    </bean>
<!--记住我管理器-->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>


    <!-- 增加session管理相关配置 -->
    <!-- 会话Cookie模板 默认可省-->
    <bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <property name="name" value="JSESSIONID04"/>
        <!-- cookie过期时间,-1:存活一个会话 ,单位:秒 ,默认为-1-->
        <property name="maxAge" value="-1"/>
        <property name="httpOnly" value="true"/>
    </bean>
<!--session管理器-->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <!-- 默认值和配置中给出的一致,所bean:sessionIdCookie 可以省略 -->
    <property name="sessionIdCookie" ref="simpleCookie"/>
    <!-- session全局超时时间, 单位:毫秒 ,30分钟 默认值为1800000   默认设置为10s-->
    <property name="globalSessionTimeout" value="10000"/>

        <!--注入session监听器-->
        <property name="sessionListeners">
            <list>
                <bean class="com.lsw.session.MySessionListener"/>
            </list>
        </property>

        <!--session检测    可以省略不写  有默认配置-->
        <!--session默认开启   但是默认时间比较长   30分钟   我们可以更改时间   来观察-->
        <property name="sessionIdUrlRewritingEnabled" value="true"/>
        <!-- 更改   检测间隔时间    15s-->
        <property name="sessionValidationInterval" value="15000"/>
    </bean>

web.xml

<!-- 会从spring工厂中获取和它同名的bean,(id="shiroFilter")
     接到请求后调用bean的doFilter方法,进行访问控制。
     因为这里本来是ShiroFilter的  我们将它放在了工厂内部  所有在web中需要定义这样一个来代替shiroFilter来拦截所有请求  然后找到工厂中预期filterName对应的ShiroFilter进行操作过滤
-->
<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>
<!-- EnvironmentLoaderListener不再需要,因为shiro环境已由spring初始化 
     springMVC,spring配置不变 -->

另外大家发现了我们在这里也直接整合了Mybatis。因为之前我们放在shiro.ini中的用户名,权限和角色信息都没有了 ,这里我们自定义了pojo类 将权限角色信息存入数据库中,在需要安全数据时候 在自定义的Realm中注入service并调用dao来进行数据库查询即可 贴一下大概结构图 和realm的代码。
大概结构:(将角色权限分别定义pojo,并将数据存在数据库,由realm中调用service,dao来查询)在这里插入图片描述
自定义realm

@Setter
public class MyRealm extends AuthorizingRealm {
    private UserService userService;//注入service  调用其中dao查询方法即可
    private  PermissionService permissionService;
    private RoleService roleService;
    @Override
    //用户做授权和权限认定
    /**
     * 当subject.login()时,shiro会调用Realm的此方法做用户信息的查询,然后做校验
     * 职责:通过用户传递来的用户名查询用户表,获得用户信息
     * 返回值:将查到的用户信息(用户名+密码)封装在AuthenticationInfo对象中返回
     * 异常:如果没有查到用户可抛出用户不存在异常;如果用户被锁定可抛出用户被锁异常;或其它自定义异常.
     * @param token
     * @return
     * @throws AuthenticationException
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取shiro中的用户名
        String username = (String) principalCollection.getPrimaryPrincipal();
        //根据用户姓名去表中查询用户角色和权限信息
        //根据用户名查询角色信息
     //   RoleService roleService = ContextLoader.getCurrentWebApplicationContext().getBean("roleServiceImpl", RoleService.class);
        Set<String> roles = roleService.queryAllRolenameByUsername(username);
        //根据用户名查权限信息
      //  PermissionService permissionService =ContextLoader.getCurrentWebApplicationContext().getBean("permissionServiceImpl", PermissionService.class);
        Set<String> permissions = permissionService.queryAllPermissionByUsername(username);
        //将用户权限和角色信息  封装到对象中
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();
        //根据用户名来查询用户身份信息
       // UserService userService = (UserService)ContextLoader.getCurrentWebApplicationContext().getBean("userServiceImpl");
        //System.out.println("================"+userService);
        User user = userService.queryUserByUsername(username);
        if(user==null){
            return null;   //返回空后续会返回一个用户名不存在异常  由一场解析器处理
        }
        return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
    }
}

至此 ,Spring集成shiro基本就完成了 后面想起来什么在做总结和大家分享 希望对大家有所帮助。

课程简介:历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值