栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Apache shiro 权限框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Apache shiro 权限框架

Apache shiro学习文档


作者:pinkhub

时间:2021/12/24

技术栈:springboot+mybatisPlus+shiro

未来,我们抱团取暖,结伴而行…


文档目录
  • Apache shiro学习文档
    • 第一章 Apache Shiro 概述
    • 第二章 Apache Shiro 架构
    • 第三章 Apache Shiro 配置
      • 3.1 配置文件(ini)配置
      • 3.2 配置类配置
    • 第四章 Apache Shiro 核心
      • 前提
      • 4.1 编码和解码算法
      • 4.2 散列算法
      • 4.3 认证
        • 认证流程
        • 案例一:登陆测试1
        • 案例二:登陆测试2
        • 案例三:登录测试3
        • 源码追踪:
      • 4.4 授权
        • 基本流程
        • ShiroConfig配置
        • 案例一:用户权限校验
    • 第五章 项目实战
      • 登录、注册、用户权限管理
      • 项目截图


第一章 Apache Shiro 概述

Apache Shiro 是一个强大而灵活的开源安全框架,可以干净地处理身份验证、授权、企业会话管理和加密。

身份验证:有时也被称为“登录”,这是一种证明用户真实身份的行为。

授权:访问控制的过程,即确定“谁”可以访问“什么”。

会话管理:管理特定于用户的会话,即使是在非 Web 或 EJB 应用程序中。

密码学:使用密码算法确保数据安全,同时仍然易于使用。


官方文档:https://shiro.apache.org/reference.html

第二章 Apache Shiro 架构

关键字:Subject、SecurityManager``和``Realms

第三章 Apache Shiro 配置 3.1 配置文件(ini)配置

基于INI配置使DefinitionRealm、definitionRealm生效

# =======================
# Shiro INI configuration
# =======================

[main]
# Objects and their properties are defined here,
# Such as the securityManager, Realms and anything
# else needed to build the SecurityManager
definitionRealm=edu.pinkhub.shrio_demo.realm.DefinitionRealm
securityManager.realms=$definitionRealm

[users]
# The 'users' section is for simple deployments
# when you only need a small number of statically-defined
# set of User accounts.
jay=1234

[roles]
# The 'roles' section is for simple deployments
# when you only need a small number of statically-defined
# roles.

[urls]
# The 'urls' section is used for url-based security
# in web applications.  We'll discuss this section in the
# Web documentation
3.2 配置类配置
@Configuration
public class ShiroConfig {
    
    @Bean("shiroRealm")
    public ShiroRealm shiroRealm(){
        return new ShiroRealm();
    }
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("shiroRealm") ShiroRealm shiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        return securityManager;
    }
}
第四章 Apache Shiro 核心 前提

导入shiro依赖:可以选择shiro-spring-boot-starter、shiro-spring、shiro-core的一个。


			org.apache.shiro
			shiro-spring-boot-starter
			1.8.0

tips:

如果选择shiro-core依赖时,版本不要太高,否则IniSecurityManagerFactory方法过时

4.1 编码和解码算法

shiro提供base64和16进制字符串编码和解码的API支持。

工具类如下:

public class EncodesUtil {
    
    public static String encodeHex(byte[] input){
        return Hex.encodeToString(input);
    }
    
    public static byte[] decodeHex(String input){
        return Hex.decode(input);
    }
    
    public static String encodebase64(byte[] input){
        return base64.encodeToString(input);
    }
    
    public static byte[] decodebase64(String input){
        return base64.decode(input);
    }
}
4.2 散列算法

散列算法用于生成数据的摘要信息,不可逆算法,常用于存储密码,常见的散列算法有:MD5、SHA等,散列的对象:“密码+salt”,salt其实是干扰数据。

散列算法的5种实现类:

tips:其中6种加密实现类继承于SimpleHash类

关键字:salt→SecureRandomNumberGenerator

​ password→SimpleHash

摘要算法工具类:用于对密码加密

 
public class DigestsUtil {
    //算法类型
    public static final String SHA1="SHA-1";
    //加密次数
    public static final Integer ITERATION=512;
    
    public static String sha1(String plaintext,String salt){
        return new SimpleHash(SHA1,plaintext,salt,ITERATION).toString();
    }
    
    public static String createSalt(){
        SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();
        return secureRandomNumberGenerator.nextBytes().toHex();
    }
    
    public static Map entryptPassword(String pwd){
        HashMap map = new HashMap<>();
        String salt=createSalt();
        String password=sha1(pwd,salt);
        map.put("salt",salt);
        map.put("password",password);
        return map;
    }
}

测试类:

System.out.println(DigestsUtil.entryptPassword("123").toString());

运行结果:

{password=54eeefc1368c375feeac0f71e1e6c929d4d5d6f1, salt=ba18ca250fd8442eaccfa3a03c3a5530}
4.3 认证

认证流程

【第一步】:Shiro把用户的数据封装成标识token,token一般封装着用户名,密码等信息 UsernamePasswordToken


【第二步】:使用Subject门面获取到封装着用户的数据的标识token subject.login(usernamePasswordToken);

【第三步】:Subject把标识token交给SecurityManager,SecurityManager再把标识token委托给认证器Authenticator进行身份验证。

​ 认证器的作用一般是用来指定如何验证,它规定本次认证用到哪些Realm

【第四步】:认证器Authenticator将传入的标识token,与数据源Realm对比,验证token是否合法

关键字:

doGetAuthenticationInfo、SimpleAuthenticationInfo

案例一:登陆测试1

数据来自shiro.ini文件

第一步:导入依赖


			org.apache.shiro
			shiro-spring-boot-starter
			1.8.0

第二步:创建shiro.ini

#声明用户账号
[users]
jay=1234

第三步:测试代码

public void shiroLogin(){
		//1.导入ini配置创建工厂
		IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		//2.通过工厂构建安全构建器
		SecurityManager securityManager = factory.getInstance();
		//3.通过工具类让安全构建器生效
		SecurityUtils.setSecurityManager(securityManager);
		//4.通过工具类获取subject主体
		Subject subject = SecurityUtils.getSubject();
		//5.构建账号和密码
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("jay", "1234");
		//6.使用subject登录
		subject.login(usernamePasswordToken);
		//7.输出状态
		System.out.println("登陆状态:"+subject.isAuthenticated());
}

截图:

案例二:登陆测试2

数据来自数据库

【第一步】:自定义realm

public class DefinitionRealm extends AuthorizingRealm {
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException     {
        String loginName = (String)authenticationToken.getPrincipal();
        //模拟数据库查询
        SecurityServiceImpl securityService = new SecurityServiceImpl();
        String password = securityService.findPasswordByUserName(loginName);
        if(password==""){
            throw new AuthenticationException("账号不存在");
        }
        return new SimpleAuthenticationInfo(loginName,password,getName());
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}

【第二步】:创建shiro.ini definitionRealm生效

[main]
definitionRealm=edu.pinkhub.shrio_demo.realm.DefinitionRealm
securityManager.realms=$definitionRealm

【第三步】:测试

@Test
	public void shiroLogin(){
		//1.导入ini配置创建工厂
		IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		//2.工厂构建安全构建器
		SecurityManager securityManager = factory.getInstance();
		//3.通过工具类让安全构建器生效
		SecurityUtils.setSecurityManager(securityManager);
		//4.通过工具获取subject主体
		Subject subject = SecurityUtils.getSubject();
		//5.构建账号和密码
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("jay", "1234");
		//6.使用subject登录
		subject.login(usernamePasswordToken);
		//7.输出状态
		System.out.println("登陆状态:"+subject.isAuthenticated());
	}
案例三:登录测试3

Realm使用散列算法模拟登录

【第一步】:创建shiro.ini,使自定义realm生效

[main]
definitionRealm=edu.pinkhub.shrio_demo.realm.DefinitionRealm
securityManager.realms=$definitionRealm

【第二步】:创建service接口

public interface SecurityService {
    Map findPasswordByUserName(String userName);
}

【第三步】:创建service实现类,模拟根据用户名从数据库查询其加密密码、角色列表、权限列表

@Service
public class SecurityServiceImpl implements SecurityService {
    @Override
    public Map findPasswordByUserName(String userName) {
        return DigestsUtil.entryptPassword("123456");
    }
}

【第四步】:创建realm

public class DefinitionRealm extends AuthorizingRealm {
    public DefinitionRealm(){
        //1.指定密码匹配方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
        //2.指定密码迭代次数
        hashedCredentialsMatcher.setHashIterations(DigestsUtil.ITERATION);
        //3.生效
        setCredentialsMatcher(hashedCredentialsMatcher);
    }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginName = (String)authenticationToken.getPrincipal();
        SecurityServiceImpl securityService = new SecurityServiceImpl();
        Map map = securityService.findPasswordByUserName(loginName);
        if(map.isEmpty()){
            throw new AuthenticationException("账号不存在");
        }
        String password=map.get("password");
        String salt = map.get("salt");
        return new SimpleAuthenticationInfo(loginName,password, ByteSource.Util.bytes(salt),getName());
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       return null;
    }
}

【第五步】:编写测试类

    @Test
	public void shiroLogin(){
		//1.导入ini配置创建工厂
		IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		//2.工厂构建安全构建器
		SecurityManager securityManager = factory.getInstance();
		//3.通过工具类让安全构建器生效
		SecurityUtils.setSecurityManager(securityManager);
		//4.通过工具获取subject主体
		Subject subject = SecurityUtils.getSubject();
		//5.构建账号和密码
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("pinkhub", "123456");
		//6.使用subject登录
		subject.login(usernamePasswordToken);
		//7.输出状态
		System.out.println("登陆状态:"+subject.isAuthenticated());
	}
源码追踪:












将token、info密码匹配结果boolean值,返回subject.isAuthenticated()

4.4 授权

前提:用户必须通过认证;角色和权限存放在数据库中

基本流程

【第一步】:首先调用Subject.isPermitted*/hasRole*接口,然后委托给SecurityManager(安全管理器)

【第二步】:SecurityManager在委托给内部组件Authorizer(授权器)

【第三步】:Authorizer再将请求委托给Realm去做

【第四步】:Realm将用户请求的参数封装成权限对象,再从我们重写的doGetAuthorizationInfo方法中获取从数据库中查询到的权限集合

【第五步】:Realm将用户传入的权限对象,与从数据库查出的权限对象进行一一对比。如果用户传入的权限对象在数据库中查出来的权限对象中,则返回true,否则返回false

关键字:doGetAuthorizationInfo、SimpleAuthorizationInfo

ShiroConfig配置

配置内容:

(1)创建自定义ShiroDbRealm实现,用于权限认证、授权、加密方式的管理,同时从数据库中取得相关的角色、资源、用户的信息,然后交于DefaultWebSecurityManager权限管理器管理

(2)创建DefaultWebSecurityManager权限管理器用于管理DefaultWebSessionManager会话管理器、ShiroDbRealm

(3)创建ShiroFilterFactoryBean的shiro过滤器指定权限管理器、同时启动连接链及登录URL、未登录的URL的跳转

(4)创建Simplecookie,访问项目时,会在客户端中cookie中存放ShiroSession

(5)创建DefaultWebSessionManager会话管理器定义cookie机制、定时刷新、全局会话超时时间然后交于DefaultWebSecurityManager权限管理器管理

@Configuration
public class ShiroConfig {
    
    @Bean("shiroDBRealm")
    public ShiroDBRealm shiroDBRealm() {
        return new ShiroDBRealm();
    }
    
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("shiroDBRealm") ShiroDBRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //拦截
        HashMap filterMap = new HashMap<>();
        //filterMap.put("/user/login", "anon");
        filterMap.put("/user/add", "perms[add]");
        filterMap.put("/user/edit", "perms[update]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        //没通过验证,触发登录拦截请求,跳转登陆页面
        shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
        //触发未认证请求,跳转未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/noAuth");
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }
}
案例一:用户权限校验

登陆状态:true
当前用户是否拥有管理员角色true
当前用户是否拥有查看订单的权限true
当前用户没有coder角色

【1】模拟从数据库查出的角色和权限列表

@Override
public Map findPasswordByUserName(String userName) {
    return DigestsUtil.entryptPassword("123456");
}
@Override
public List findRoleByUserName(String userName) {
     List roleList = new ArrayList();
     roleList.add("admin");
     roleList.add("dev");
     roleList.add("student");
     return roleList;
}
@Override
public List findPermissionByUserName(String UserName) {
    List list=new ArrayList();
    list.add("order:add");
    list.add("order:del");
    list.add("order:update");
    list.add("order:query");
    return list;
}

【2】编写doGetAuthorizationInfo

public class DefinitionRealm extends AuthorizingRealm {
    public DefinitionRealm(){
        //1.指定密码匹配方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
        //2.指定密码迭代次数
        hashedCredentialsMatcher.setHashIterations(DigestsUtil.ITERATION);
        //3.生效
        setCredentialsMatcher(hashedCredentialsMatcher);
     }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException     {
        String loginName = (String)authenticationToken.getPrincipal();
        System.out.println(loginName);
        SecurityServiceImpl securityService = new SecurityServiceImpl();
        Map map = securityService.findPasswordByUserName(loginName);
        if(map.isEmpty()){
            throw new AuthenticationException("账号不存在");
        }
        System.out.println(getName());
        String password=map.get("password");
        String salt = map.get("salt");
        return new SimpleAuthenticationInfo(loginName,password, ByteSource.Util.bytes(salt),getName());
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        //用户凭证信息,当前账户名
        String primaryPrincipal = (String)principal.getPrimaryPrincipal();
        //从数据库中查询用户的角色和权限
        SecurityServiceImpl securityService = new SecurityServiceImpl();
        List roles = securityService.findRoleByUserName(primaryPrincipal);
        List permissions = securityService.findPermissionByUserName(primaryPrincipal);
        //构建资源校验对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRoles(roles);
        authorizationInfo.addStringPermissions(permissions);
        return authorizationInfo;
    }
}

【3】编写测试代码

    @Test
	public Subject login(){
		//1.导入ini配置创建工厂
		IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		//2.工厂构建安全构建器
		SecurityManager securityManager = factory.getInstance();
		//3.通过工具类让安全构建器生效
		SecurityUtils.setSecurityManager(securityManager);
		//4.通过工具获取subject主体
		Subject subject = SecurityUtils.getSubject();
		System.out.println(subject);
		//5.构建账号和密码
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("pinkhub", "123456");
		//6.使用subject登录
		subject.login(usernamePasswordToken);
		return subject;
	}
@Test
public void testRole(){
		Subject subject = login();
		System.out.println("登陆状态:"+subject.isAuthenticated());
		System.out.println("当前用户是否拥有管理员角色"+subject.hasRole("admin"));
		System.out.println("当前用户是否拥有查看订单的权限"+subject.isPermitted("order:query"));
		try{
			subject.checkRole("coder");
		}catch(Exception e){
			System.out.println("当前用户没有coder角色");
		}
}

【4】运行截图

第五章 项目实战 登录、注册、用户权限管理

前提:准备user表;导入shiro依赖;导入DigestsUtil.java 、 Result.java 、 ResultCode.java工具类

框架:sprintboot+mybatisPlus+shiro+thymeleaf

项目结构图:

【第0步】准备工作

(1)添加依赖

        
			org.springframework.boot
			spring-boot-starter-web
		
        
		
			org.projectlombok
			lombok
			true
		
		
		
			mysql
			mysql-connector-java
			5.1.49
		
		
		
			com.baomidou
			mybatis-plus-boot-starter
			3.4.3.3
		
        
		
			com.alibaba
			druid-spring-boot-starter
			1.2.8
		
        
		
			org.apache.shiro
			shiro-spring-boot-starter
			1.8.0
		
        
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
			2.6.1
		
       
		
			com.github.theborakompanioni
			thymeleaf-extras-shiro
			2.1.0
		

(2)编写配置文件yml

server:
  port: 8847

spring:
  datasource:
    druid:
      username: root
      password: 123456
      url: jdbc:mysql://localhost:3306/books
      #url: jdbc:mysql://localhost:3306/books?useUnicode=true&&characterEncoding=utf-8&&useSSL=false&serverTimezone=GMT%2b8

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

【第一步】编写User实体类

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User implements Serializable {
    @TableId(value = "id",type = IdType.AUTO)
    public Integer id;
    
    @TableField("account")
    public String account;
    @TableField("real_name")
    public String realName;
    @TableField("password")
    public String password;
    @TableField("salt")
    public String salt;
    @TableField("title")
    public String title;
    @TableField("status")
    public Integer status;
    @TableField("user_id")
    public String userId;
    @TableField("perms")
    public String perms;
}

【第二步】编写mapper层

@Mapper
public interface UserMapper extends baseMapper {}

【第三步】编写service层

---------------------------------------UserService.java-------------------------------------------------------------------------
public interface UserService extends IService {}

---------------------------------------UserServiceImpl.java---------------------------------------------------------------------
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {}

【第四步】编写controller

Application.java

@Controller
public class AppplicationController {
    @RequestMapping({"/","/index"})
    public String index(Model model){
        model.addAttribute("msg","hello,shiro");
        return "login";
    }
}

UserController.java

@RequestMapping("/user/")
@Controller
public class UserControlller {
    @Autowired
    public UserService userService;
    @RequestMapping("toRegister")
    public String toRegister(){
        return "register";
    }
    @PostMapping("register")
    public String register(HttpServletRequest request, Model model){
        String account = request.getParameter("account");
        String _password = request.getParameter("password");
        Map info = DigestsUtil.entryptPassword(_password);
        String password = info.get("password");
        String salt = info.get("salt");
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("account",account);
        User userDB = userService.getOne(wrapper);
        if(userDB!=null){
            model.addAttribute("msg","账号已存在");
            return "register";
        }else{
            User user = new User();
            user.setAccount(account);
            user.setPassword(password);
            user.setSalt(salt);
            user.setRealName("pinkhub");
            user.setStatus(1);
            Random random = new Random();
            user.setUserId(Integer.toString(random.nextInt(1000)));
            user.setTitle("普通用户");
            user.setPerms("query,update");
            userService.save(user);
            return "login";
        }
    }
    @PostMapping("login")
    public String login(String account,String password, Model model){
        UsernamePasswordToken token = new UsernamePasswordToken(account, password);
        Subject subject = SecurityUtils.getSubject();
        try{
            subject.login(token);
            return "index";
        }catch(UnknownAccountException e){
            model.addAttribute("msg","账号不正确");
            return "login";
        }catch(IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }
    @RequestMapping("add")
    public String add(){
        return "/user/add";
    }
    @RequestMapping("edit")
    public String edit(){
        return "/user/edit";
    }
    @RequestMapping("noAuth")
    public String noAuth(){
        return "noAuth";
    }
    @RequestMapping("toLogin")
    public String toLogin(){
        return "login";
    }

【第五步】编写realm

ShiroDBRealm.java

public class ShiroDBRealm extends AuthorizingRealm {
   @Autowired
   public UserService userService;

   public ShiroDBRealm(){
      //指定密码匹配方式
      HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
      //指定密码迭代次数
      matcher.setHashIterations(DigestsUtil.ITERATION);
      //匹配生效
      setCredentialsMatcher(matcher);
   }
   
   @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
      System.out.println("执行了doGetAuthenticationInfo()方法");
      UsernamePasswordToken tk=(UsernamePasswordToken) token;
      QueryWrapper wrapper = new QueryWrapper();
      wrapper.eq("account",tk.getUsername());
      User user = userService.getOne(wrapper);
      if(user==null){
         return null;
      }
      Subject subject = SecurityUtils.getSubject();
      Session session = subject.getSession();
      session.setAttribute("loginUser",user);
      return new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
   }
   
   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
      System.out.println("执行了doGetAuthorizationInfo()方法");
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      Subject subject = SecurityUtils.getSubject();
      //认证成功后,返回信息的第一个参数
      User user = (User)subject.getPrincipal();
      System.out.println(user);
      List permList = new ArrayList<>();
      String[] perms = user.getPerms().split(",");
      for(String perm:perms){
         permList.add(perm);
      }
      info.addStringPermissions(permList);
      return info;
   }
}

【第六步】编写config

ShiroConfig.java

@Configuration
public class ShiroConfig {
    
    @Bean("shiroDBRealm")
    public ShiroDBRealm shiroDBRealm() {
        return new ShiroDBRealm();
    }
    
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("shiroDBRealm") ShiroDBRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //拦截
        HashMap filterMap = new HashMap<>();
        //filterMap.put("/user/login", "anon");
        filterMap.put("/user/add", "perms[add]");
        filterMap.put("/user/edit", "perms[update]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        //没通过验证,触发登录拦截请求,跳转登陆页面
        shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
        //触发未认证请求,跳转未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/noAuth");
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }
    //整合ShiroDialect:用于整合shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

【第七步】编写前端页面

index.html




    
    shiro
    



首页


login.html




    
    shiro
    



登陆页面


账号:

密码:

无账号,去注册

noAuth.html




    
    shiro
    



该用户无权限

register.html




    
    shiro
    



注册页面


账号:

密码:

add.html




    
    shiro
    



shiro权限控制

退出

增加用户

edit.html




    
    shiro
    



shiro权限控制

退出

修改用户

项目截图



账号:00

密码:000000 权限:update


账号:qiang

密码:000000 权限:add


ending.....
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/677235.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号