美文网首页
Shiro框架学习

Shiro框架学习

作者: 花开半時偏妍 | 来源:发表于2020-06-30 11:45 被阅读0次

    1.基本知识

    四大基石----身份验证,授权,会话管理,加密
    1.Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
    2.Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
    3.Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
    4.Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
    除以上功能外,shiro还提供了很多扩展如下

    Web Support:Web支持,可以非常容易的集成到Web环境;

    Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

    Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

    Testing:提供测试支持;

    Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

    Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

    记住一点,Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。

    2.过滤器权限拦截器

    过滤器简称
    对应的java类

    anon 例子/admins/**=anon 没有参数,表示可以匿名使用
    authc 例子/admins/user/**=authc 表示需要认证(登录)才能使用,没有参数
    roles(角色) 例子/admins/user/**=roles[admin] 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
    perms(权限) 例子/admins/user/*=perms[user:add:] 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/=perms["user:add:,user:modify:"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
    rest 例子/admins/user/**=rest[user] 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
    port 例子/admins/user/**=port[8081] 当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
    authcBasic 例如/admins/user/**=authcBasic 没有参数表示httpBasic认证
    ssl 例子/admins/user/**=ssl 没有参数,表示安全的url请求,协议为https
    user 例如/admins/user/**=user 没有参数表示必须存在用户,当登入操作时不做检查
    默认过滤器名 指定类名 说明
    认证过滤器
    authc FormAuthenticationFilter—基于表单的过滤器; 如“/**=authc”没有登录会跳到相应页登录;主要属性:usernameParam:表单提交的用户名参数;passwordParam:表单提交的密码参数;rememberMeParam:表单提交叫记住我;loginUrl:登录页地址;successUrl登录成功后的默认重定向地址;failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure);
    authc Basic BasicHttpAuthenticationFilter—HTTP身份验证过滤器 主要属性:applicationName:弹出登录框显示的信息(application);
    logout LogoutFilter—退出过滤器 主要属性:redirectUrl:退出成功后重定向的地址(/);示例“/logout=logout”
    user UserFilter—用户过滤器 用户已经身份验证/记住我登录的都可;示例 “/**=user”
    anon AnonymousFilter—匿名过滤器 即不需要登录即可访问;一般用于静态资源过滤;示例 “/static/**=anon”
    授权过滤器
    roles RolesAuthorizationFilter—角色授权过滤器 验证用户是否拥有所有角色;主要属性:loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]”
    perms PermissionsAuthorizationFilter—权限授权过滤器 验证用户是否拥有所有权限;属性和 roles 一样;示例“/user/**=perms["user:create"]”
    host HostFilter—即主机过滤器 比如其提供了属性:authorizedIps:已授权的 ip 地址,deniedIps:表示拒绝的 ip 地址;不过目前还没有完全实现,不可用。
    port PortFilter—端口过滤器 主要属性:port(80):可以通过的端口;示例 “/test= port[80]”,如果用户访问该页面是非 80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
    rest HttpMethodPermissionFilter—rest风格过滤器 自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll);
    ssl slFilter—SSL过滤器 只有请求协议是https才能通过;否则自动跳转会 https 端口(443);其他和port过滤器一样;
    其它过滤器
    noSessionCreati on NoSessionCreationFilter—不创建会话过滤器 调用 subject.getSession(false)不会有什么问题,但是如果subject.getSession(true)将抛出DisabledSessionException 异常;

    3.引入shiro依赖

            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.2</version>
            </dependency>
    
    <!--  mysql驱动  -->
    <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    <!--  lombok插件  -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
    <!--  swagger2 API管理测试 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.9.2</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.9.2</version>
            </dependency>
    <!--  springboot -->
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    <!--  jpa依赖 -->
      <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    

    4.yml配置文件

    #用的是mysql8.0版本
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
        username: root
        password: root
      jpa:
        hibernate:
          ddl-auto: update #指定为update,每次启动项目检测表结构有变化的时候会新增字段,表不存在时会新建,如果指定create,则每次启动项目都会清空数据并删除表,再新建
          naming:
            physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl #按字段名字建表
            #implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl #驼峰自动映射为下划线格式
        show-sql: true # 默认false,在日志里显示执行的sql语句
        database: mysql
        database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    

    5.Realm配置

    import com.example.shiro.entity.Permission;
    import com.example.shiro.entity.Role;
    import com.example.shiro.entity.User;
    import com.example.shiro.service.UserService;
    import org.apache.shiro.authc.*;
    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 javax.annotation.Resource;
    
    public class MyShiroRealm extends AuthorizingRealm {
        @Resource
        private UserService userService;
    
        /**
         * 身份认证:验证用户输入的账号和密码是否正确。
         * */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //获取用户输入的账号
            String userName = (String) token.getPrincipal();
            //通过username从数据库中查找 User对象.
            //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
            User user = userService.findByUserName(userName);
            if (user == null) {
                return null;
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    user,//这里传入的是user对象,比对的是用户名,直接传入用户名也没错,但是在授权部分就需要自己重新从数据库里取权限
                    user.getPassword(),//密码
                    ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt
                    getName()//realm name
            );
            return authenticationInfo;
        }
    
        /**
         * 权限信息
         * */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            //如果身份认证的时候没有传入User对象,这里只能取到userName
            //也就是SimpleAuthenticationInfo构造的时候第一个参数传递需要User对象
            User user  = (User)principals.getPrimaryPrincipal();
            for(Role role : user.getRoleList()){
                //添加角色
                authorizationInfo.addRole(role.getRole());
                for(Permission p:role.getPermissions()){
                    //添加权限
                    authorizationInfo.addStringPermission(p.getPermission());
                }
            }
            return authorizationInfo;
        }
    
    }
    

    6.Shiro配置

    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    @Configuration
    public class ShiroConfig {
        //将自己的验证方式加入容器
        @Bean
        MyShiroRealm myShiroRealm() {
            MyShiroRealm myShiroRealm = new MyShiroRealm();
            myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            return myShiroRealm;
        }
    
        //权限管理,配置主要是Realm的管理认证
        @Bean
        DefaultWebSecurityManager securityManager() {
            DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
            manager.setRealm(myShiroRealm());
            return manager;
        }
    
        //凭证匹配器(密码校验交给Shiro的SimpleAuthenticationInfo进行处理)
        @Bean
        public HashedCredentialsMatcher hashedCredentialsMatcher(){
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
            hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
            hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
            return hashedCredentialsMatcher;
        }
    
        // Filter工厂,设置对应的过滤条件和跳转条件
        @Bean
        ShiroFilterFactoryBean shiroFilterFactoryBean() {
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            bean.setSecurityManager(securityManager());
            Map<String, String> filterMap = new HashMap<String, String>();
            // 登出
            filterMap.put("/logout", "logout");
            // swagger
            filterMap.put("/swagger**/**", "anon");
            filterMap.put("/webjars/**", "anon");
            filterMap.put("/v2/**", "anon");
            // 对所有用户认证
            filterMap.put("/**", "authc");
            // 登录
            bean.setLoginUrl("/login");
            // 首页
            bean.setSuccessUrl("/index");
            // 未授权页面,认证不通过跳转
            bean.setUnauthorizedUrl("/403");
            bean.setFilterChainDefinitionMap(filterMap);      
            return bean;
        }
    
        //开启shiro aop注解支持.
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
            return authorizationAttributeSourceAdvisor;
        }
    
        //shiro注解模式下,登录失败或者是没有权限都是抛出异常,并且默认的没有对异常做处理,配置一个异常处理
        @Bean(name="simpleMappingExceptionResolver")
        public SimpleMappingExceptionResolver
        createSimpleMappingExceptionResolver() {
            SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
            Properties mappings = new Properties();
            mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
            mappings.setProperty("UnauthorizedException","/403");
            r.setExceptionMappings(mappings);  // None by default
            r.setDefaultErrorView("error");    // No default
            r.setExceptionAttribute("exception");     // Default is "exception"
            return r;
        }
    }
    

    7.swagger2配置

    import io.swagger.annotations.ApiOperation;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
       @Bean
       public Docket api() {
           return new Docket(DocumentationType.SWAGGER_2)
                   .apiInfo(apiInfo())
                   .select()
                   .apis(RequestHandlerSelectors.any())
                   .paths(PathSelectors.any()).build();
       }
       private static ApiInfo apiInfo() {
           return new ApiInfoBuilder()
                   .title("API文档")
                   .description("Swagger API 文档")
                   .version("1.0")
                   .contact(new Contact("name..", "url..", "email.."))
                   .build();
       }
    }
    

    8.其他类

    8.1创建实体类

    User

    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.format.annotation.DateTimeFormat;
    import javax.persistence.*;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.util.List;
    
    @Entity
    @Getter
    @Setter
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long userId;
    
        @Column(nullable = false, unique = true)
        private String userName; //登录用户名
    
        @Column(nullable = false)
        private String name;//名称(昵称或者真实姓名,根据实际情况定义)
    
        @Column(nullable = false)
        private String password;
    
        private String salt;//加密密码的盐
    
        private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
    
        @ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;
        @JoinTable(name = "UserRole", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
        private List<Role> roleList;// 一个用户具有多个角色
    
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
        private LocalDateTime createTime;//创建时间
    
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate expiredDate;//过期日期
    
        private String email;
    
        /**密码盐. 重新对盐重新进行了定义,用户名+salt,这样就不容易被破解 */
        public String getCredentialsSalt(){
            return this.userName+this.salt;
        }
    }
    

    说明:
    这里使用@Getter,@Setter注解,不能使用@Data注解,因为实体使用了jpa的@oneToMany ,加载方式为lazy,在主表查询时关联表未加载,而主表使用@Data后会实现带关联表属性的hashCode和equals等方法。在运行过程中调用关联表数据时会显示异常 java.lang.stackoverflowerror。
    Role

    import lombok.Getter;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.util.List;
    
    @Entity
    @Getter
    @Setter
    public class Role {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long roleId; // 编号
    
        @Column(nullable = false, unique = true)
        private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
    
        private String description; // 角色描述,UI界面显示使用
    
        private Boolean available = Boolean.TRUE; // 是否可用,如果不可用将不会添加给用户
    
        //角色 -- 权限关系:多对多关系;
        @ManyToMany(fetch= FetchType.EAGER)
        @JoinTable(name="RolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
        private List<Permission> permissions;
    
        // 用户 - 角色关系定义;
        @ManyToMany
        @JoinTable(name="UserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")})
        private List<User> users;// 一个角色对应多个用户
    }
    

    Permission

    import lombok.Getter;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.util.List;
    
    @Entity
    @Getter
    @Setter
    public class Permission {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long permissionId;//主键.
    
        @Column(nullable = false)
        private String permissionName;//名称.
    
        @Column(columnDefinition="enum('menu','button')")
        private String resourceType;//资源类型,[menu|button]
    
        private String url;//资源路径.
    
        private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
    
        private Long parentId; //父编号
    
        private String parentIds; //父编号列表
    
        private Boolean available = Boolean.TRUE;
    
        //角色 -- 权限关系:多对多关系;
        @ManyToMany(fetch= FetchType.EAGER)
        @JoinTable(name="RolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
        private List<Role> roles;
    }
    

    LoginResult

    import lombok.Data;
    
    @Data
    public class LoginResult {
        private boolean isLogin = false;
        private String result;
    }
    

    8.2Dao类

    BaseRepository

    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.data.repository.NoRepositoryBean;
    import org.springframework.data.repository.PagingAndSortingRepository;
    
    import java.io.Serializable;
    
    @NoRepositoryBean
    public interface BaseRepository<T, I extends Serializable> extends PagingAndSortingRepository<T, I>, JpaSpecificationExecutor<T> {
    }
    

    UserRepository

    import com.example.shiro.entity.User;
    
    public interface UserRepository extends BaseRepository<User,Long> {
        User findByUserName(String userName);
    }
    

    8.3Service

    LoginService

    import com.example.shiro.model.LoginResult;
    
    public interface LoginService {
    
        LoginResult login(String userName, String password);
    
        void logout();
    }
    

    UserService

    import com.example.shiro.entity.User;
    
    public interface UserService {
        User findByUserName(String userName);
    }
    

    8.4Service.impl

    LoginServiceImpl

    import com.example.shiro.model.LoginResult;
    import com.example.shiro.repository.UserRepository;
    import com.example.shiro.service.LoginService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Service;
    
    @Service
    public class LoginServiceImpl implements LoginService {
    
        @Override
        public LoginResult login(String userName, String password) {
            LoginResult loginResult = new LoginResult();
            if (userName == null || userName.isEmpty()) {
                loginResult.setLogin(false);
                loginResult.setResult("用户名为空");
                return loginResult;
            }
            String msg = "";
            // 1、获取Subject实例对象
            Subject currentUser = SecurityUtils.getSubject();
    
    //        // 2、判断当前用户是否登录
    //        if (currentUser.isAuthenticated() == false) {
    //
    //        }
    
            // 3、将用户名和密码封装到UsernamePasswordToken
            UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
    
            // 4、认证
            try {
                currentUser.login(token);// 传到MyAuthorizingRealm类中的方法进行认证
                Session session = currentUser.getSession();
                session.setAttribute("userName", userName);
                loginResult.setLogin(true);
                return loginResult;
                //return "/index";
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                msg = "UnknownAccountException -- > 账号不存在:";
            } catch (IncorrectCredentialsException e) {
                msg = "IncorrectCredentialsException -- > 密码不正确:";
            } catch (AuthenticationException e) {
                e.printStackTrace();
                msg = "用户验证失败";
            }
    
            loginResult.setLogin(false);
            loginResult.setResult(msg);
    
            return loginResult;
        }
    
        @Override
        public void logout() {
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
        }
    }
    

    UserServiceImpl

    import com.example.shiro.entity.User;
    import com.example.shiro.repository.UserRepository;
    import com.example.shiro.service.UserService;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    @Service
    public class UserServiceImpl implements UserService {
        @Resource
        private UserRepository userRepository;
        @Override
        public User findByUserName(String userName) {
            return userRepository.findByUserName(userName);
        }
    }
    

    8.5controller

    LoginController

    import com.example.shiro.entity.User;
    import com.example.shiro.model.LoginResult;
    import com.example.shiro.service.LoginService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class LoginController {
        @Resource
        private LoginService loginService;
    
        @GetMapping(value = "/login")
        public String login() {
            return "登录页";
        }
    
        @PostMapping(value = "/login")
        public String login(@RequestBody User user) {
            System.out.println("login()");
            String userName = user.getUserName();
            String password = user.getPassword();
            LoginResult loginResult = loginService.login(userName,password);
            if(loginResult.isLogin()){
                return "登录成功";
            } else {
                return "登录失败:" + loginResult.getResult();
            }
        }
    
        @GetMapping(value = "/index")
        public String index() {
            return "主页";
        }
    
        @GetMapping(value = "/logout")
        public String logout() {
            return "退出";
        }
    
        @GetMapping("/403")
        public String unauthorizedRole(){
            return "没有权限";
        }
    }
    

    UserController

    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
        //用户查询
        @GetMapping("/userList")
        @RequiresPermissions("user:view")//权限管理;
        public String userInfo(){
            return "userList";
        }
    
        //用户添加
        @GetMapping("/userAdd")
        @RequiresPermissions("user:add")//权限管理;
        public String userInfoAdd(){
            return "userAdd";
        }
    
        //用户删除
        @GetMapping("/userDel")
        @RequiresPermissions("user:del")//权限管理;
        public String userDel(){
            return "userDel";
        }
    }
    

    9.数据库文件

    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for hibernate_sequence
    -- ----------------------------
    DROP TABLE IF EXISTS `hibernate_sequence`;
    CREATE TABLE `hibernate_sequence`  (
      `next_val` bigint(20) NULL DEFAULT NULL
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of hibernate_sequence
    -- ----------------------------
    INSERT INTO `hibernate_sequence` VALUES (1);
    INSERT INTO `hibernate_sequence` VALUES (1);
    INSERT INTO `hibernate_sequence` VALUES (1);
    
    -- ----------------------------
    -- Table structure for permission
    -- ----------------------------
    DROP TABLE IF EXISTS `permission`;
    CREATE TABLE `permission`  (
      `permissionId` int(11) NOT NULL,
      `available` int(255) NULL DEFAULT NULL,
      `permissionname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `parentid` int(11) NULL DEFAULT NULL,
      `parentids` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `permission` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `resourcetype` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `url` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      PRIMARY KEY (`permissionId`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of permission
    -- ----------------------------
    INSERT INTO `permission` VALUES (1, 1, '用户管理', 0, '0/', 'user:view', 'menu', 'user/userList');
    INSERT INTO `permission` VALUES (2, 1, '用户添加', 1, '0/1', 'user:add', 'button', 'user/userAdd');
    INSERT INTO `permission` VALUES (3, 1, '用户删除', 1, '0/1', 'user:del', 'button', 'user/userDel');
    
    -- ----------------------------
    -- Table structure for role
    -- ----------------------------
    DROP TABLE IF EXISTS `role`;
    CREATE TABLE `role`  (
      `roleid` int(11) NOT NULL,
      `available` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `role` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`roleid`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of role
    -- ----------------------------
    INSERT INTO `role` VALUES (1, '1', '管理员', 'admin');
    
    -- ----------------------------
    -- Table structure for rolepermission
    -- ----------------------------
    DROP TABLE IF EXISTS `rolepermission`;
    CREATE TABLE `rolepermission`  (
      `permissionid` int(11) NOT NULL,
      `roleid` int(11) NULL DEFAULT NULL,
      PRIMARY KEY (`permissionid`) USING BTREE,
      INDEX `FKoucecfqc8mdel2gdbo0e62mv`(`roleid`) USING BTREE,
      CONSTRAINT `FKed6d8k3dnq28rvnoboj6y6dg3` FOREIGN KEY (`permissionid`) REFERENCES `permission` (`permissionId`) ON DELETE RESTRICT ON UPDATE RESTRICT,
      CONSTRAINT `FKoucecfqc8mdel2gdbo0e62mv` FOREIGN KEY (`roleid`) REFERENCES `role` (`roleid`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of rolepermission
    -- ----------------------------
    INSERT INTO `rolepermission` VALUES (1, 1);
    INSERT INTO `rolepermission` VALUES (3, 1);
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `userId` int(11) NOT NULL,
      `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `password` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      `salt` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      `state` int(255) NULL DEFAULT NULL,
      `createTime` datetime(0) NULL DEFAULT NULL,
      `email` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
      `expiredDate` date NULL DEFAULT NULL,
      PRIMARY KEY (`userId`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES (1, 'admin', '管理员', '6214e2068f13bd77460bbe7e8cdc8440', 'cmhit', 1, NULL, NULL, NULL);
    
    -- ----------------------------
    -- Table structure for userrole
    -- ----------------------------
    DROP TABLE IF EXISTS `userrole`;
    CREATE TABLE `userrole`  (
      `roleid` int(11) NOT NULL,
      `userId` int(11) NULL DEFAULT NULL,
      PRIMARY KEY (`roleid`) USING BTREE,
      INDEX `FK9e1tcga17su515dcucrlj3vtj`(`userId`) USING BTREE,
      CONSTRAINT `FK63vxkaqx2q3q577qvuqhbtqs8` FOREIGN KEY (`roleid`) REFERENCES `role` (`roleid`) ON DELETE RESTRICT ON UPDATE RESTRICT,
      CONSTRAINT `FK9e1tcga17su515dcucrlj3vtj` FOREIGN KEY (`userId`) REFERENCES `user` (`userId`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of userrole
    -- ----------------------------
    INSERT INTO `userrole` VALUES (1, 1);
    
    SET FOREIGN_KEY_CHECKS = 1;
    

    10.运行即可进行API接口测试

    相关文章

      网友评论

          本文标题:Shiro框架学习

          本文链接:https://www.haomeiwen.com/subject/hgvtqktx.html