SpringMVC框架下使用shiro权限管理

简单的实现shiro权限管理

1.添加shiro依赖(版本1.2.4)

<!--shiro版本-->
<shiro.version>1.2.4</shiro.version>
<!-- shiro -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>${shiro.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>${shiro.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-web</artifactId>
  <version>${shiro.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>${shiro.version}</version>
</dependency>

2.pojo类,我把User/Role统一放在user表里,而且没有权限表,如下:

使用lombok插件,可以省略setter和getter之类的配置。

package entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class User {
    private Integer id;
    private String name;
    private String password;
    //user,admin,president
    private String role;
}

3.自定义MyRealm,需要继承AuthorizingRealm类,并重新两个方法:

public class MyRealm extends AuthorizingRealm {
    @Autowired
    UserDao userDao;

    //权限认证
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();//获取用户名
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole(userDao.getUserByName(username).getRole());
//        List<String> list = new ArrayList<>();
//        list.add("/user");
//        list.add("/admin");
//        list.add("/president");
//        authorizationInfo.addStringPermissions(list);
        return authorizationInfo;
    }

//    登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();
        User user = userDao.getUserByName(username);
        if (user != null) {
            return new SimpleAuthenticationInfo(user.getName(),user.getPassword(),"myRealm");
        } else {
            return null;
        }

    }
}

4.在spring配置文件中加入shiro配置

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

    <!--0.使用注解驱动-->
    <context:annotation-config/>
    <!--自动扫描注解注入类### dao层@Repository ### service层@Service ###不知道类型@Compnent-->
    <context:component-scan base-package="dao,entity,service,service.impl,util"/>
    <!--1.配置资源-->
    <bean id="dataSource"
          class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/db?characterEncoding=utf-8&amp;serverTimezone=GMT%2B8&amp;useSSL=false"/>
        <property name ="username" value="root"/>
        <property name="password" value="123456"/>
        <!--连接池一些属性设置-->
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="3" />
        <property name="maxActive" value="80" />
        <property name="maxWait" value="5000" />
        <!-- 自动清除无用连接 -->
        <property name="removeAbandoned" value="true"/>
        <!-- 清除无用连接的等待时间 -->
        <property name="removeAbandonedTimeout" value="180"/>
        <!-- 连接属性 -->
        <property name="connectionProperties" value="clientEncoding=UTF-8"/>
    </bean>

    <!--2. 配置sqlSessionFactory-->
    <bean id ="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 指定数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 自动扫描mapper.xml文件 -->
        <property name="mapperLocations">
            <array>
                <value>classpath:UserMapper.xml</value>
            </array>
        </property>
    </bean>
    <!--3.扫描映射器通过扫描方式配置-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="dao"/>
    </bean>

    <!-- 4.事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--注入jdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--******************shiro***************************-->
    <!-- 自定义Realm -->
    <bean id="myRealm" class="config.MyRealm"/>

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

    <!-- Shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 身份认证失败,则跳转到登录页面的配置 -->
        <property name="loginUrl" value="/login"/>
        <!-- 权限认证失败,则跳转到指定页面 -->
        <property name="unauthorizedUrl" value="/unauthorized"/>
        <!-- Shiro连接约束配置,即过滤链的定义 -->
        <property name="filterChainDefinitions">
            <value>
                /login=anon
                /static/**=authc
                /user/**=authc,roles[user]
                /admin/**=authc,roles[admin]
                /president/**=authc,roles[president]

                <!--/login=anon-->
                <!--/user/admin*=authc-->
                <!--/user/student*/**=roles[teacher]-->
                <!--/user/teacher*/**=perms["user:create"]-->
            </value>
        </property>
    </bean>
    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <!-- 开启Shiro注解 -->
    <!-- 开启shiro的注解支持 -->
    <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!-- 必须改为true,即使用cglib方式为Action创建代理对象。默认值为false,使用JDK创建代理对象,会造成问题 -->
        <property name="proxyTargetClass" value="true"/>
    </bean>
    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
    <!-- 会话管理器,设定会话超时及保存 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- 全局会话超时时间(单位毫秒),默认30分钟 -->
        <property name="globalSessionTimeout" value="1800000" />
        <property name="sessionDAO" ref="sessionDAO"/>
    </bean>
    <!-- 会话验证调度器,每30分钟执行一次验证 -->
    <!-- <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"> -->
    <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
        <property name="interval" value="1800000"/>
        <property name="sessionManager" ref="sessionManager"/>
    </bean>
    <!-- sessionDAO保存认证信息 -->
    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
        <property name="cacheManager" ref="shiroCacheManager" />
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>
    <!-- 用户授权信息Cache, 采用EhCache -->
    <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    </bean>
    <!-- AOP式方法级权限检查 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true" />
    </bean>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>
</beans>

5.controller写login及其他接口用来测试

package controller;


import dao.UserDao;
import entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping
public class UserController {
    @Resource
    UserDao userDao;

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    @ResponseBody
    public  String login(String name, String password, HttpServletRequest request) {
        User user = userDao.getUserByName(name);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(name,password);
        try {
            subject.login(token);
            request.getSession().setAttribute("user", user);
            return "redirect:/user";
        } catch (Exception e) {
            request.setAttribute("error","用户名或密码错误");
            return "retry to login";
        }
    }

    @ResponseBody
    @RequestMapping("/user")
    public String user(HttpServletRequest request) {
        return "user login success";
    }

    @ResponseBody
    @RequestMapping("/admin")
    public String admin(HttpServletRequest request) {
        return "admin login success";
    }

    @ResponseBody
    @RequestMapping("/static")
    public String stat(HttpServletRequest request) {
        return "static is free field";
    }

    @ResponseBody
    @RequestMapping("/president")
    public String president(HttpServletRequest request) {
        return "president login success";
    }

    @ResponseBody
    @RequestMapping("/unauthorized")
    public String unauthorized(HttpServletRequest request) {
        return "unauthorized role";
    }

}

6.使用的都是Json,测试登录就可以发现shiro已经进行了权限管控,如下只有user角色的权限几个测试结果:

static测试结果

猜你喜欢

转载自blog.csdn.net/weixin_42058600/article/details/81385066