• 通过shiro进行按钮及页面访问url的权限控制


    1.当面我们每次登录系统时,都会通过我们自己定义的继承AuthorizingRealm的ShiroRealm进行用户账号密码的确认以及拥有权限的查询:

    (1)自定义shiroReam:

    public class ShiroDbRealm extends AuthorizingRealm {
      
        @Autowired
    	private UserService userService;
    	@Autowired
    	private SysUserService sysUserService ;
    	@Autowired
    	private SysUserResService sysUserResService ;
    	public ShiroDbRealm() {
    		super();
    	}
     
    	/**
    	 * 验证登陆
    	 */
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
    			throws AuthenticationException {
    		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    		SysUser sysUser = sysUserService.getUserByLoginName(token.getUsername()) ;
    		//根据登录名获取用户信息
    		if (sysUser != null) {
    			return new SimpleAuthenticationInfo(sysUser.getUserNo(), sysUser.getUserPwd(), getName());
    		} else {
    			throw new AuthenticationException();
    		}
    	}
     
    	/**
    	 * 登陆成功之后,进行角色和权限验证
    	 */
    	@Override
    	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
     
    		String userNo = (String) getAvailablePrincipal(principals);
    		// 列举此用户所有的权限
    		//List permissions = userService.findUserPermissionByName(username);
    		List listRes = sysUserResService.getPermissionByNo(userNo) ;
    		Set strs=new HashSet();
    		Iterator it = listRes.iterator();
    		while (it.hasNext()) {
    			SysUserRes re=it.next();
    			strs.add(re.getResUrl());
    		}
    		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    		authorizationInfo.addStringPermissions(strs);
    		return authorizationInfo;
    	}
     
    	/**
    	 * 清除所有用户授权信息缓存.
    	 */
    	public void clearCachedAuthorizationInfo(String principal) {
    		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
    		clearCachedAuthorizationInfo(principals);
    	}
     
    	/**
    	 * 清除所有用户授权信息缓存.
    	 */
    	public void clearAllCachedAuthorizationInfo() {
    		Cache cache = getAuthorizationCache();
    		if (cache != null) {
    			for (Object key : cache.keys()) {
    				cache.remove(key);
    			}
    		}
    	}
    	/**
    	 * 
    	* @Title: clearAuthz 
    	* @Description: TODO 清楚缓存的授权信息  
    	* @return void    返回类型
    	 */
    	public void clearAuthz(){
    		this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    (2)通过siro进行处理:shiro的配置文件

    
    
     
    	
    		
    		
    	
     
    	
    	
    		 
    	
     
    	
    	
    		
    		
    		
    		
    	
    		
    			
    				/sysUser/checkLogin = anon
    				/login = anon
    				/index = anon
    				/page/** = anon
    				
    				
    				/sysUser/list= perms["user:serch"]
    				/sysUser/toAdd = perms["user:add"]
    				/sysUser/toEdit = perms["user:update"]
    				
    				/sysRole/list=perms["role:serch"]
    				/sysUser/toAdd = perms["role:add"]
    				/sysUser/toEdit = perms["role:update"]
    				
    				/sysDept/list = perms["dept:serch"]
    				/sysDept/toAdd = perms["dpt:add"]
    				/sysDept/toEdit = perms["dept:edit"]
    				
    				/sysRes/list = perms["res:serch"]
    				/sysRes/toAdd = perms["res:add"]
    				/sysRest/toEdit = perms["res:edit"]
    			
    		
    	 
     
    	
    	
     
    	
    	
    		
    	
    	
    	
     
    	
    	
    	
     
    	
    		
    	
    	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    (3)拦截配置说明:

    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:8081queryString,其中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没有参数表示必须存在用户,当登入操作时不做检查
    注:anon,authcBasic,auchc,user是认证过滤器,
    perms,roles,ssl,rest,port是授权过滤器

    (4)我的配置:

    /sysRes/list = perms[“res:serch”]
    /sysRes/toAdd = perms[“res:add”]
    /sysRest/toEdit = perms[“res:edit”]

    如果你想要访问主界面(/sysRes/list)就必修又有[“res:serch”]的权限

    如果你想要跳转到添加界面(/sysRes/toAdd),就必须拥有[“res:add”]的权限

    如果你想跳转到修改界面(/sysRest/toEdit),就必须拥有[“res:edit”]的权限

    2.按钮权限的控制就显得简单了,只需要通过shiro的标签就轻而易举的解决了:

    	
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.补充点:

    身份验证相关的
    在这里插入图片描述

    授权相关的
    在这里插入图片描述
    其他
    在这里插入图片描述

    Shiro 标签

    Shiro 提供了 JSTL 标签用于在 JSP 页面进行权限控制,如根据登录用户显示相应的页面按钮。
    guest 标签:用户没有身份验证时显示相应信息,即游客访问信息:
    在这里插入图片描述
    user 标签:用户已经经过认证/记住我登录后显示相应的信息。

    Shiro 标签

    authenticated 标签:用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的
    在这里插入图片描述
    notAuthenticated 标签:用户未进行身份验证,即没有调用Subject.login进行登录,包括记住我自动登录的也属于
    未进行身份验证。
    在这里插入图片描述
    pincipal 标签:显示用户身份信息,默认调用Subject.getPrincipal() 获取,即 Primary Principal。
    在这里插入图片描述
    hasRole 标签:如果当前 Subject 有角色将显示 body 体内容:
    在这里插入图片描述
    hasAnyRoles 标签:如果当前Subject有任意一个角色(或的关系)将显示body体内容。
    在这里插入图片描述
    lacksRole:如果当前 Subject 没有角色将显示 body 体内容
    在这里插入图片描述
    hasPermission:如果当前 Subject 有权限将显示 body 体内容
    在这里插入图片描述
    lacksPermission:如果当前Subject没有权限将显示body体内容。
    在这里插入图片描述

    权限注解

    @RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;即 Subject. isAuthenticated() 返回 true
    @RequiresUser:表示当前 Subject 已经身份验证或者通过记住我登录的。
    @RequiresGuest:表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。
    @RequiresRoles(value={“admin”, “user”}, logical=Logical.AND):表示当前 Subject 需要角色 admin 和user
    @RequiresPermissions (value={“user:a”, “user:b”},logical= Logical.OR):表示当前 Subject 需要权限 user:a 或user:b。

    自定义拦截器

    通过自定义拦截器可以扩展功能,例如:动态url-角色/权限访问控制的实现、根据 Subject 身份信息获取用户信息绑定到 Request(即设置通用数据)、验证码验证、在线用户信息的保存等

    会话相关的 API

    Subject.getSession():即可获取会话;其等价于Subject.getSession(true),即如果当前没有创建 Session 对象会创建
    一个;Subject.getSession(false),如果当前没有创建 Session 则返回null
    session.getId():获取当前会话的唯一标识
    session.getHost():获取当前Subject的主机地址
    session.getTimeout() & session.setTimeout(毫秒):获取/设置当前Session的过期时间
    session.getStartTimestamp() & session.getLastAccessTime():获取会话的启动时间及最后访问时间;如果是 JavaSE 应用需要自己定期调用 session.touch() 去更新最后访问时间;如果是Web 应用,每次进入 ShiroFilter 都会自动调用 session.touch() 来更新最后访问时间。
    session.touch() & session.stop():更新会话最后访问时间及销毁会话;当Subject.logout()时会自动调用 stop 方法来销毁会话。如果在web中,调用 HttpSession. invalidate()也会自动调用Shiro Session.stop 方法进行销毁Shiro 的会话
    session.setAttribute(key, val) &session.getAttribute(key) &session.removeAttribute(key):设置/获取/删除会话属性;在整个会话范围内都可以对这些属性进行操作

  • 相关阅读:
    太坑了吧!一次某某云上的redis读超时排查经历
    中国日用化工市场竞争格局展望及未来战略分析报告2022年版
    AI全流程开发难题破解之钥
    基于单片机和ICL7135多档位数字电压表设计
    Taurus.MVC WebAPI 入门开发教程8:WebAPI文档与自动化测试。
    Rust开发——Struct使用示例
    QT5到QT6产生的一些变化【QT环境搭建篇】
    抗锯齿的线
    jdbc-plus是一款基于JdbcTemplate增强工具包, 基于JdbcTemplate已实现分页、多租户等插件,可自定义扩展插件
    双碳时代下,数据中心PUE划红线
  • 原文地址:https://blog.csdn.net/m0_67392931/article/details/126618393