Spring集成Shiro使用小结

shiro的认证流程

Spring集成Shiro使用小结_第1张图片

Application Code:应用程序代码,由开发人员负责开发的
Subject:框架提供的接口,代表当前用户对象
SecurityManager:框架提供的接口,代表安全管理器对象
Realm:可以开发人员编写,框架也提供一些,类似于DAO层,用于访问权限数据
Spring集成Shiro使用小结_第2张图片

引入maven依赖


   
        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-allartifactId>
            <version>1.3.2version>
        dependency>
        
        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-springartifactId>
            <version>1.4.0version>
        dependency>

配置web.xml


    

    <filter>
        <filter-name>shiroFilterfilter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>

    filter>

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

在Spring配置文件中配置shiro



    

    
    <bean id="myRealm" class="top.wintp.crud.service.MyRealm"/>


    
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
    bean>


    
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        
        <property name="securityManager" ref="securityManager"/>


        

        <property name="loginUrl" value="/user/login.do"/>
        
        <property name="unauthorizedUrl" value="/user/unAuth.do"/>


        
        <property name="filterChainDefinitions">
            <value>
                /static/** = anon
                /user/login.do=anon
                /user/loginUser.do=anon
                /emp/findAll.do=perms["admin"]
                /** = authc
            value>
        property>

    bean>

MyRealm

package top.wintp.crud.service;

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.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

import top.wintp.crud.dao.TUserMapper;
import top.wintp.crud.entity.TUser;
import top.wintp.crud.entity.TUserExample;

/**
 * 类描述:
 * 

* 作者: pyfysf *

* qq: 337081267 *

* CSDN: http://blog.csdn.net/pyfysf *

* 个人博客: http://wintp.top *

* 邮箱: [email protected] *

* 时间:2018/8/22 */ public class MyRealm extends AuthorizingRealm { @Autowired private TUserMapper mTUserMapper; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("自定义realm授权方法"); @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("自定义realm授权方法"); TUser user = (TUser) principalCollection.getPrimaryPrincipal(); System.out.println(user.getUsername()); System.out.println(user.getPassword()); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addStringPermission("admin"); //授权 return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("自定义realm认证方法"); UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; TUserExample tUserExample = new TUserExample(); tUserExample.createCriteria().andUsernameEqualTo(token.getUsername()); List tUsers = mTUserMapper.selectByExample(tUserExample); if (tUsers != null && tUsers.size() > 0) { TUser tUser = tUsers.get(0); //简单认证信息对象 AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(tUser, tUser.getPassword(), this.getName()); //认证 return authenticationInfo; } else { return null; } } }

修改用户登录的方法

@Service
public class UserService {

    public boolean loginUser(TUser user) {

        String username = user.getUsername();


        //shiro执行过程  获取当前用户--subject -->然后获取securityManager(安全管理器)(login 登录)
        // 然后调用realm

        //获取当前用户对象 -- 未认证
        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token
                = new UsernamePasswordToken(user.getUsername(), user.getPassword());

        try {
            subject.login(token);


            TUser resultUer = (TUser) subject.getPrincipal();

            System.out.println("登录成功");

            return true;


        } catch (Exception e) {
        //代表认证失败
            e.printStackTrace();

            return false;
        }
    }
}

常用过滤器配置简称

Spring集成Shiro使用小结_第3张图片

注解式编程

首先需要在Spring的配置文件中开启Shiro的注解支持:在applicationContext.xml中加入下面代码:


    
    <bean id="advisorAutoProxyCreator"
          class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        
        <property name="proxyTargetClass" value="true"/>
    bean>

    
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

有了上面的配置,我们就可以在我们的代码中使用Shiro的注解进行权限控制了:


    @RequestMapping("/findAll")
   @RequiresPermissions("emp-check")
    public String findAll(Model model, @RequestParam(value = "pageNum", defaultValue = "1")
            Integer pageNum) {

        logger.info("请求开始>>>>>");

        //书写分页逻辑--在这里进行分页声明之后,后面紧跟的查询就是一个分页目标
        //第二个参数是指定每次查询几条数据
        PageHelper.startPage(pageNum, 5);

        //调用Service里面的方法进行使用
        List allEmployees = mEmployeeService.findAll();
        //使用PageInfo来包装返回的数据--可以更好的管理分页逻辑

        //第二个参数是页面上最多显示几个页数,比如限制只显示5个那么就为1,2,3,4,5
        //2,3,4,5,6||||3,4,5,6,7
        PageInfo employeePageInfo = new PageInfo(allEmployees, 5);

        logger.info("数据为:" + employeePageInfo);

        logger.info("请求结束>>>>>");

        //存储数据,跳转界面
        model.addAttribute("employeePageInfo", employeePageInfo);
        return "list";
    }

中途遇到的问题

配置注解之后,没有起到任何作用。
可能一:在你的spring的配置文件中忽略扫描Controller注解,然而你在Controller中使用了@RequiresPermissions,那么我们需要把上面注解支持的代码配置到Spring-mvc.xml文件中。


    
    <context:component-scan base-package="top.wintp.crud">
        
        <context:exclude-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>

    context:component-scan>

如果有上面的配置,那么spring将不会扫描到Controller注解

可能二:在你的spring-mvc中仅仅只是扫描到了Controller注解,然而你在service层或者dao层用到了@RequiresPermissions,那么我们需要把上面注解支持的代码配置到applicationContext.xml文件中。

  <context:component-scan base-package="top.wintp.crud" use-default-filters="false">
        
        <context:include-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>

    context:component-scan>

建议:在Spring的主配置文件中和Springmvc的配置文件中都加入对shiro注解的支持。特别注意:如果两个配置文件中都配置了,注意其id不能相同

在jsp中使用shiro提供的标签库

一、引入标签库
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
二、使用合适的标签在合适的位置进行使用

例如:

<shiro:hasPermission name="admin">

    <button class="btn btn-primary" id="btn_add_emp">新增button>
    <button class="btn btn-danger btn_all_del">删除button>
shiro:hasPermission>

上述代码为,当当前用户具有admin的权限时,新增和删除按钮才会显示

你可能感兴趣的:(Spring集成Shiro使用小结)