Shiro整合SSM 实现认证、授权、会话管理、多Realm、记住我功能

一、环境搭建

1.1 pom.xml引入依赖

  • shiro依赖:
    <!--shiro  start-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.4.1</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.6.11</version>
    </dependency>
    <!--shiro   end-->
  • ssm+shiro所有依赖:
 <properties>
        <spring.version>4.3.30.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

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

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument-tomcat</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.7</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.7</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.7</version>
        </dependency>
        <!--打印日志 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.2</version>
        </dependency>
    </dependencies>

1.2 SSM其他配置文件整合(省略)

ssm配置整合

1.3 web.xml配置shiro的代理filter

<!--
    配置Shiro的核心代理对象
  -->
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <!--
        参数的意义:
        默认targetFilterLifecycle为false,当他为false的时候shiroFilter代理对象默认加入到IOC容器中
        并且在IOC容器中遵循IOC的生命周期管理,将其设置为true,让其受tomcat容器生命周期管理
    	将Filter的生命周期交给Tomcat服务器
    -->
    <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.4 applicatioContext.xml中配置

  1. 开启shiro在controller层的注解功能

  2. ShiroFilter配置

  3. 配置web的安全管理器
    在安全管理器中设置多Realm管理器
    配置多Realm
    记住我
    会话管理

  4. 配置多Realm管理器
    设置多Realm管理器的策略

  5. 配置自定义realm

  6. 会话管理


    <!--开启shiro注解功能-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"></property>
    </bean>

    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"></property>
    </bean>


    <!--
        ShiroFilter配置
     -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!--配置安全管理器-->
        <property name="securityManager" ref="securityManager"></property>
    </bean>

    <!--配置web的安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--在安全管理器中设置多Realm管理器,重点: 多Realm策略,authenticator必须配置在realms上面,否则认证不通过-->
        <property name="authenticator" ref="modularRealmAuthenticator"></property>
        <!--配置多Realm-->
        <property name="realms">
            <list>
                <ref bean="sysUserRealm1"></ref>
            </list>
        </property>

        <!--配置完会话之后将其设置到安全管理器中-->
        <!-- 会话管理-->
        <!--<property name="sessionManager" ref="defaultWebSessionManager"></property>-->
        
        <!--记住我,此时会话管理的10秒期限将被覆盖了,没有用了-->
        <property name="rememberMeManager">
            <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager">
                <property name="cookie">
                    <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                        <!--自定义cookie名称-->
                        <constructor-arg value="qianfeng"></constructor-arg>
                        <!--防止前端js使用document.cookie获取cookie-->
                        <property name="httpOnly" value="true"></property>
                        <!--过期时间,默认在浏览器关闭是过期 -1 有效期30天-->
                        <property name="maxAge" value="2592000"></property>
                    </bean>
                </property>
            </bean>
        </property>
        
    </bean>

    <!--配置多Realm管理器-->
    <bean id="modularRealmAuthenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
        <!--设置多Realm管理器的策略-->
        <property name="authenticationStrategy">
            <!--
              FirstSuccessfulStrategy : 当有一个Realm认证成功就为成功,只返回第一个Realm身份验证 成功的认证信息,其他的忽略
              AtLeastOneSuccessfulStrategy(默认策略 ):只要有一个Realm验证成功即可,返回所有Realm身份验证成功的认证信息
              AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败
            -->
            <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
        </property>
    </bean>

    <!--配置自定义realm1-->
    <bean id="sysUserRealm1" class="com.qianfeng.realm.SysUsersRealm1">
        <!--设置加密方式-->
        <property name="credentialsMatcher" ref="credentialsMatcher"></property>
    </bean>

    <!--
        配置Realm1密码加密
        注意:加密方式是   MD5
     -->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="MD5"></property>
        <property name="hashIterations" value="1024"></property>
    </bean>


    <!--    会话管理
    <bean id="defaultWebSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        &lt;!&ndash;设置超时时间&ndash;&gt;
        <property name="globalSessionTimeout" value="10000"></property>
    </bean>
-->
    

1.5 dispatcherServlet-servlet.xml中配置

<!--开启shiro注解-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"></property>
    </bean>

1.4 多Realm实现(常用)

  • Shiro中提供了一个多Realm的管理类ModularRealmAuthenticator帮助Shiro框架进行多个Realm管理
<!--配置web的安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!--在安全管理器中设置多Realm管理器,重点: 多Realm策略,authenticator必须配置在realms上面,否则认证不通过-->
    <property name="authenticator" ref="modularRealmAuthenticator"></property>
    <!--配置多Realm-->
    <property name="realms">
        <list>
            <ref bean="userRealm01"></ref>
            <ref bean="userRealm02"></ref>
        </list>
    </property>
</bean>

<!--配置多Realm管理器,realm策略管理-->
<bean id="modularRealmAuthenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
    <!--设置多Realm管理器的策略-->
    <property name="authenticationStrategy">
          <!--
              FirstSuccessfulStrategy : 当有一个Realm认证成功就为成功,只返回第一个Realm身份验证 成功的认证信息,其他的忽略
              AtLeastOneSuccessfulStrategy(默认策略 ):只要有一个Realm验证成功即可,返回所有Realm身份验证成功的认证信息
              AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败
            -->
        <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
    </property>
</bean>

<!--配置Realm01-->
<bean id="userRealm01" class="com.qianfeng.shiro.SysUserRealm">
    <!--使用内部bean设置加密方式-->
    <property name="credentialsMatcher">
        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
            <property name="hashAlgorithmName" value="MD5"></property>
            <property name="hashIterations" value="1024"></property>
        </bean>
    </property>
</bean>

<!--配置Realm02-->
<bean id="userRealm02" class="com.qianfeng.shiro.SysUserRealm">
    <property name="credentialsMatcher">
        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
            <property name="hashAlgorithmName" value="SHA-1"></property>
            <property name="hashIterations" value="1024"></property>
        </bean>
    </property>
</bean>

1.6 Shiro的会话管理

  • Shiro多采用DefaultWebSessionManager进行会话管理
<!--会话管理-->
<bean id="webSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <!--会话超时时间,单位毫秒-->
    <property name="globalSessionTimeout" value="10000"></property>
</bean>

<!--配置完会话之后将其设置到安全管理器中-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    
    <!--会话管理-->
    <property name="sessionManager" ref="webSessionManager"></property>
    
</bean>

1.7 记住我功能

1.7.1 在配置文件中配置记住我功能(在安全管理器中)

<!--配置web的安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--在安全管理器中设置多Realm管理器,重点: 多Realm策略,authenticator必须配置在realms上面,否则认证不通过-->
        <property name="authenticator" ref="modularRealmAuthenticator"></property>
        <!--配置多Realm-->
        <property name="realms">
            <list>
                <ref bean="sysUserRealm1"></ref>
            </list>
        </property>

        <!--配置完会话之后将其设置到安全管理器中-->
        <!-- 会话管理-->
        <!--<property name="sessionManager" ref="defaultWebSessionManager"></property>-->

        <!--记住我,此时会话管理的10秒期限将被覆盖了,没有用了-->
        <property name="rememberMeManager">
            <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager">
                <property name="cookie">
                    <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                        <!--自定义cookie名称-->
                        <constructor-arg value="qianfeng"></constructor-arg>
                        <!--防止前端js使用document.cookie获取cookie-->
                        <property name="httpOnly" value="true"></property>
                        <!--过期时间,默认在浏览器关闭是过期 -1 有效期30天-->
                        <property name="maxAge" value="2592000"></property>
                    </bean>
                </property>
            </bean>
        </property>

    </bean>

1.7.2 控制器中修改登陆的规则(在登陆中调用Shiro记住我API方法)

 /**
     * 认证(登录)
     * @param username
     * @param password
     * @param rm
     * @param model
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(String username, String password, String rm,Model model){

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

        //获取当前用户实体
        Subject subject = SecurityUtils.getSubject();

        //将前端发送过来的用户名和密码封装进token中,调用subject中的login方法将其发送到安全管理器中
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);

        //记住我
        if(rm!=null && rm.equals("1")){
            token.setRememberMe(true);//调用Shiro记住我API方法
        }

        try {
            //将用户名和密码发送到安全管理器
            subject.login(token);
        } catch (UnknownAccountException uae) {
            System.out.println("账户不存在....");
            model.addAttribute("msg","账户不存在");
            return "login";
        } catch (IncorrectCredentialsException ice) {
            System.out.println("密码错误....");
            model.addAttribute("msg","密码错误");
            return "login";
        }catch (AuthenticationException ae) {
            ae.printStackTrace();
            System.out.println("其他认证异常...."+ae.getMessage());
            model.addAttribute("msg","其他异常...");
            return "login";
        }
        //登陆成功跳转列表页(列表页需要认证才可以访问)
        return "home";
    }

1.7.4 测试(打开浏览器调试模式)

  • 记住我 登录后 会看见cookie
    在这里插入图片描述

1.8 控制层代码编写


    /**
     * 认证(登录)
     * @param empName
     * @param empPassword
     * @param rm
     * @param model
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public Result login(String empName , String empPassword, String rm, Model model){

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

        Result result = new Result();
        Message message=new Message();
        result.setMessage(message);

        //获取当前用户实体
        Subject subject = SecurityUtils.getSubject();

        //将前端发送过来的用户名和密码封装进token中,调用subject中的login方法将其发送到安全管理器中
        UsernamePasswordToken token = new UsernamePasswordToken(empName,empPassword);

        //记住我
        if(rm!=null && rm.equals("1")){
            token.setRememberMe(true);//调用Shiro记住我API方法
        }

        try {
            //将用户名和密码发送到安全管理器
            subject.login(token);
        } catch (UnknownAccountException uae) {
            System.out.println("账户不存在....");
            throw  new OaException(OaEnum.LOGIN1_ERROR);
        } catch (IncorrectCredentialsException ice) {
            System.out.println("密码错误....");
            throw  new OaException(OaEnum.LOGIN2_ERROR);
        }catch (AuthenticationException ae) {
            ae.printStackTrace();
            System.out.println("其他认证异常...."+ae.getMessage());
            throw  new OaException(OaEnum.LOGIN3_ERROR);
        }
        //登陆成功
        return result;
    }


1.9 统一异常处理捕获异常


    /**
     * 捕获未认证、未授权异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {Exception.class})
    public Result excetion(Exception e) {
        System.out.println("进入异常");
        e.printStackTrace();
        Result result = new Result();

        if (e instanceof UnauthenticatedException) {
            System.out.println("未认证异常");
            result.setMessage(new Message(901,"未认证异常"));
            return result;
        } else if (e instanceof UnauthorizedException) {
            System.out.println("未授权异常");
            result.setMessage(new Message(902,"未授权异常"));
            return result;
        }

        return result;
    }

2.0 自定义Realm

package com.qianfeng.realms;

import com.qianfeng.entity.*;
import com.qianfeng.service.*;
import jdk.nashorn.internal.parser.Token;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义realm,实现从数据库中获取认证和授权数据,返回给安全管理器
 */
public class SysUserRealm extends AuthorizingRealm {

    @Autowired
    private SysUsersService sysUsersService;
    @Autowired
    private SysRolesService sysRolesService;
    @Autowired
    private SysUsersRolesService sysUsersRolesService;
    @Autowired
    private SysPermissionsService sysPermissionsService;
    @Autowired
    private SysRolesPermissionsService sysRolesPermissionsService;

    /**
     * 授权数据获取
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //获取用户名
        String username = principals.getPrimaryPrincipal().toString();
        //根据用户名查询用户信息
        SysUsers user = sysUsersService.getUserByUserName(username);
        //根据用户ID查询角色ID列表
        List<SysUsersRoles> usersRolesList = sysUsersRolesService.getSysUsersRolesList(user.getUserId());
        //将当前用户下的所有角色名称封装进SimpleAuthorizationInfo对象中
        HashSet<String> roles = new HashSet<>();

        //遍历查询出来的角色列表
        for (SysUsersRoles sysUsersRoles : usersRolesList) {

            Set<String> ps =  new HashSet<>();
            //根据角色ID查询角色信息
            SysRoles sysRoles = sysRolesService.getSysRolesByRoleId(sysUsersRoles.getRoleId());
            //将sysRoles的角色名称添加到SimpleAuthorizationInfo中
            roles.add(sysRoles.getRoleName());
            //通过角色ID,查询权限ID列表
            List<SysRolesPermissions> sysRolesPermissions = sysRolesPermissionsService.getSysRolesPermissionsListByRoleId(sysRoles.getRoleId());

            for (SysRolesPermissions sysRolesPermission : sysRolesPermissions) {
                //通过权限ID查询权限名称
                SysPermissions permissions = sysPermissionsService.getSysPermissionsByPermissionId(sysRolesPermission.getPermissionId());
                //将permission的名称加入到SimpleAuthorizationInfo里面
                ps.add(permissions.getPermissionName());
            }
            info.addStringPermissions(ps);

        }

        info.setRoles(roles);
        return info;
    }

    /**
     * 封装认证信息到安全管理器
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取用户名
        String principal = token.getPrincipal().toString();
        SysUsers user = sysUsersService.getUserByUserName(principal);
       // System.out.println("realm获取user:"+user);

        //用户名不存在
        if (user==null){
            // SimpleAuthenticationInfo info1 = new SimpleAuthenticationInfo();
            return null;
        }
        String salt = user.getSalt();
        ByteSource credentialsSalt = ByteSource.Util.bytes(salt);
        //封装数据库中的用户名 和 密码
        //通过SimpleAuthenticationInfo对象传递给安全管理器
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),credentialsSalt,getName());

        return info;
    }
}

2.1 数据库SQL准备

在这里插入图片描述

  • SQL语句:
-- 1.sys_users用户表

CREATE TABLE sys_users (
  user_id bigint PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
  username VARCHAR (100) UNIQUE COMMENT '用户名',
  password VARCHAR(100) COMMENT '密码',
  salt VARCHAR(100) COMMENT '盐值'
) charset=utf8 ENGINE=InnoDB COMMENT="用户表";

-- 2.sys_roles角色表

CREATE TABLE sys_roles (
  role_id bigint PRIMARY KEY AUTO_INCREMENT COMMENT '角色编号',
  role_name VARCHAR(100) COMMENT '角色名称'
) charset=utf8 ENGINE=InnoDB COMMENT="角色表";

-- 3.sys_permissions权限表(或资源表)

CREATE TABLE sys_permissions (
  permission_id bigint PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
  permission_name VARCHAR(100) COMMENT '权限'
) charset=utf8 ENGINE=InnoDB COMMENT="权限表";

-- 4.sys_users_roles用户-角色关联表

CREATE TABLE sys_users_roles (
  ur_id  bigint PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
  user_id bigint COMMENT '用户编号',
  role_id bigint COMMENT '角色编号'
) charset=utf8 ENGINE=InnoDB COMMENT="用户-角色关联表";


-- 5.sys_roles_permissions角色-权限关联表(或角色-资源关联表)
CREATE TABLE sys_roles_permissions (
  rp_id bigint PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
  role_id bigint COMMENT '角色编号',
  permission_id bigint COMMENT '权限编号'
) charset=utf8 ENGINE=InnoDB COMMENT="角色-权限关联表";

2.2 shiro注解解释

自己百度

2.3 备注

  • shiro认证是项目完成后再加上去的
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值