1 需求01

  用户进行过认证登录后,某些接口是有权限限制的;如何实现只有相应权限的用户才可以调用相应接口

2 修改shiro配置类  ShiroConfiguration

package cn.xiangxu.apache_shiro;

import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; /**
* Shiro配置类
*/
@Configuration
public class ShiroConfiguration { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login"); // 定义登录的url
shiroFilterFactoryBean.setSuccessUrl("/index"); // 定义登录成功后的url
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 没有权限时跳转的url LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 请求拦截配置
filterChainDefinitionMap.put("/index", "authc");
filterChainDefinitionMap.put("/login", "anon"); // 排除 login 的验证
filterChainDefinitionMap.put("/loginUser", "anon"); // 排除 loginUser 的验证
filterChainDefinitionMap.put("/admin", "roles[admin]");
filterChainDefinitionMap.put("/**", "user"); // 所有请求都必须进行登录过滤
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean;
} @Bean
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(authRealm);
return defaultWebSecurityManager;
} /** 注入自定义密码比较器 */
@Bean
public CredentialMather credentialMather() {
return new CredentialMather();
} /** 注入自定义的授权、认证登录类 */
@Bean
public AuthRealm authRealm(@Qualifier("credentialMather") CredentialMather credentialMather) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(credentialMather);
return authRealm;
} /** Shiro与Spring整合配置 */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
} }

  

  代码解释:只用用户角色为 admin 的用户才可以访问 /admin 接口

  原理请参见 RolesAuthorizationFilter 源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.shiro.web.filter.authz; import java.io.IOException;
import java.util.Set;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils; public class RolesAuthorizationFilter extends AuthorizationFilter {
public RolesAuthorizationFilter() {
} public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = this.getSubject(request, response);
String[] rolesArray = (String[])((String[])mappedValue);
if (rolesArray != null && rolesArray.length != 0) {
Set<String> roles = CollectionUtils.asSet(rolesArray);
return subject.hasAllRoles(roles);
} else {
return true;
}
}
}

RolesAuthorizationFilter

3 修改授权、认证登录配置类 AuthRealm

package cn.xiangxu.apache_shiro;

import cn.xiangxu.apache_shiro.model.Permission;
import cn.xiangxu.apache_shiro.model.Role;
import cn.xiangxu.apache_shiro.model.User;
import cn.xiangxu.apache_shiro.service.UserService;
import org.apache.commons.collections.CollectionUtils;
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.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList;
import java.util.List;
import java.util.Set; /**
* 自定义授权、认证登录类
*/
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UserService userService; // 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User)principalCollection.fromRealm(this.getClass().getName()).iterator().next(); // 从session中获取用户信息
List<String> permissionList = new ArrayList<>(); // 用于存放用户的权限列表
List<String> roleNameList = new ArrayList<>(); // 用于存放用户角色名称
Set<Role> roleSet = user.getRoleSet(); // 从用户信息中获取用户角色
if (CollectionUtils.isNotEmpty(roleSet)) {
for (Role role : roleSet) {
roleNameList.add(role.getRname());
Set<Permission> permissionSet = role.getPermissionSet();
if (CollectionUtils.isNotEmpty(permissionSet)) {
for (Permission permission : permissionSet) {
permissionList.add(permission.getPname());
}
}
}
} SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissionList);
info.addRoles(roleNameList); return info;
} // 认证登录(使用用户名和密码进行登录认证)
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)authenticationToken;
String username = usernamePasswordToken.getUsername(); // 取出用户名
User user = userService.findByUsername(username); // 根据用户名到数据库中去获取用户信息
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
}

  

  代码解释:将用户的角色名称提取出来并添加到 SimpleAuthorizationInfo 对象中

4 需求02

  一个用户已经认证登录成功,根据他所拥有的权限来判定他可以访问那些接口

 

5 重写shiro配置类  ShiroConfiguration

package cn.xiangxu.apache_shiro;

import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; /**
* Shiro配置类
*/
@Configuration
public class ShiroConfiguration { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login"); // 定义登录的url
shiroFilterFactoryBean.setSuccessUrl("/index"); // 定义登录成功后的url
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 没有权限时跳转的url LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 请求拦截配置
filterChainDefinitionMap.put("/index", "authc");
filterChainDefinitionMap.put("/login", "anon"); // 排除 login 的验证
filterChainDefinitionMap.put("/loginUser", "anon"); // 排除 loginUser 的验证
filterChainDefinitionMap.put("/admin", "roles[admin]"); // 角色限定
filterChainDefinitionMap.put("/edit", "perms[edit]"); // 权限限定
filterChainDefinitionMap.put("/**", "user"); // 所有请求都必须进行登录过滤
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean;
} @Bean
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(authRealm);
return defaultWebSecurityManager;
} /** 注入自定义密码比较器 */
@Bean
public CredentialMather credentialMather() {
return new CredentialMather();
} /** 注入自定义的授权、认证登录类 */
@Bean
public AuthRealm authRealm(@Qualifier("credentialMather") CredentialMather credentialMather) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(credentialMather);
return authRealm;
} /** Shiro与Spring整合配置 */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
} }

  

  代码解释:只有拥有 edit 权限的用户才可以访问 /edit 接口

  原理请参见 PermissionsAuthorizationFilter 源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.shiro.web.filter.authz; import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject; public class PermissionsAuthorizationFilter extends AuthorizationFilter {
public PermissionsAuthorizationFilter() {
} public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = this.getSubject(request, response);
String[] perms = (String[])((String[])mappedValue);
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
} return isPermitted;
}
}

PermissionsAuthorizationFilter

6 接口总汇

package cn.xiangxu.apache_shiro.controller;

import cn.xiangxu.apache_shiro.model.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.*; import javax.servlet.http.HttpSession; //@RestController // 前后端分离时使用的注解
@Controller // 前后端不分离使用的注解
public class TestController { @RequestMapping(value = "/unauthorized")
public String unauthorized() {
return "unauthorized";
} @GetMapping("/login")
public String login() {
return "login";
} @GetMapping(value = "/index")
public String index() {
return "index";
} @GetMapping(value = "/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
if (subject != null) {
subject.logout();
}
return "login";
} @GetMapping(value = "/admin")
@ResponseBody
public String admin() {
return "admin success";
} @GetMapping(value = "/edit")
@ResponseBody
public String edit() {
return "edit success";
} // 前后端不分离的写法
@PostMapping("/loginUser")
public String loginUser(
@RequestParam("username") String username,
@RequestParam("password") String password,
HttpSession session
) {
System.out.println("进入登录接口");
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject(); // 获取主体 // 认证登录逻辑(调用AuthRealm类的相关方法进行认证登录)
try {
subject.login(token); // 调用主体的login方法进行认证登录
User user = (User)subject.getPrincipal(); // 如果认证登录成功后就可以从主体中获取到数据库中主体对应的信息
session.setAttribute("user", user); // 将从数据库中获取到的主体信息放到session中,以便在权限验证的时候使用
return "index"; // 认证登录成功后就进入主页面
} catch (Exception e) {
e.printStackTrace();
return "login"; // 认证登录失败就进入登录页面
}
} // 前后端分离的写法
// @PostMapping("/loginUser")
// public String loginUser(
// @RequestBody User formUser,
// HttpSession session
// ) {
// System.out.println("进入登录接口" + formUser);
// UsernamePasswordToken token = new UsernamePasswordToken(formUser.getUsername(), formUser.getPassword());
// Subject subject = SecurityUtils.getSubject();
//
// try {
// System.out.println("进入捕获01");
// subject.login(token);
// User user = (User)subject.getPrincipal();
// System.out.println(user);
// session.setAttribute("user", user);
// System.out.println("进入捕获02");
// return "index"; // 热证登录成功就返回提示信息,在前端进行主页面跳转
// } catch (Exception e) {
// e.printStackTrace();
// return "login"; // 认证登录失败就返回提示信息,在前端进行登录页面跳转
// }
// }
}

7 开启Shiro缓存

  从 AuthorizingRealm 源码可以看出, AuthorizingRealm 可以依赖注入 CacheManager 来实现缓存

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.shiro.cache; public interface CacheManager {
<K, V> Cache<K, V> getCache(String var1) throws CacheException;
}

  技巧:CacheManager有两个实现类 -> 一个是MemoryConstrainedCacheManager, 一个是AbstractCacheManager

  只需要在shiro配置类中注入authRealm这个bean时添加一行代码就可以开启shiro缓存功能

  

package cn.xiangxu.apache_shiro;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; /**
* Shiro配置类
*/
@Configuration
public class ShiroConfiguration { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login"); // 定义登录的url
shiroFilterFactoryBean.setSuccessUrl("/index"); // 定义登录成功后的url
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 没有权限时跳转的url LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 请求拦截配置
filterChainDefinitionMap.put("/index", "authc");
filterChainDefinitionMap.put("/login", "anon"); // 排除 login 的验证
filterChainDefinitionMap.put("/loginUser", "anon"); // 排除 loginUser 的验证
filterChainDefinitionMap.put("/admin", "roles[admin]"); // 角色限定
filterChainDefinitionMap.put("/edit", "perms[edit]"); // 权限限定
filterChainDefinitionMap.put("/**", "user"); // 所有请求都必须进行登录过滤
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean;
} @Bean
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(authRealm);
return defaultWebSecurityManager;
} /** 注入自定义密码比较器 */
@Bean
public CredentialMather credentialMather() {
return new CredentialMather();
} /** 注入自定义的授权、认证登录类 */
@Bean
public AuthRealm authRealm(@Qualifier("credentialMather") CredentialMather credentialMather) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCacheManager(new MemoryConstrainedCacheManager()); // 开启内存缓存
authRealm.setCredentialsMatcher(credentialMather);
return authRealm;
} /** Shiro与Spring整合配置 */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
} }

  

package com.mmall.demo2;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import javax.sql.DataSource; @Configuration
public class DruidConfiguration { @Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
//白名单:
servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
//IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的即提示:Sorry, you are not permitted to view this page.
servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
//登录查看信息的账号密码.
servletRegistrationBean.addInitParameter("loginUsername", "druid");
servletRegistrationBean.addInitParameter("loginPassword", "12345678");
//是否能够重置数据.
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
} @Bean
public FilterRegistrationBean statFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
//添加过滤规则.
filterRegistrationBean.addUrlPatterns("/*");
//添加不需要忽略的格式信息.
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
} @Bean
PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
} //配置数据库的基本链接信息
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource") //可以在application.properties中直接导入
public DataSource dataSource() {
return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
} @Bean
public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
bean.setMapperLocations(resolver.getResources("classpath:/mappers/*.xml"));
return bean;
}
}

druid配置类

    

Shrio00 Shiro角色授权、Shiro权限授权、开启Shiro缓存的更多相关文章

  1. JAVAEE——BOS物流项目11:在realm中授权、shiro的方法注解权限控制、shiro的标签权限控制、总结shiro的权限控制方式、权限管理

    1 学习计划 1.在realm中进行授权 2.使用shiro的方法注解方式权限控制 n 在spring文件中配置开启shiro注解支持 n 在Action方法上使用注解 3.★使用shiro的标签进行 ...

  2. 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)

    前言: shiro因为其简单.可靠.实现方便而成为现在最常用的安全框架,那么这篇文章除了会用简洁明了的方式讲一下基于spring的shiro详细配置和登录注销功能使用之外,也会根据惯例在文章最后总结一 ...

  3. 将 Shiro 作为应用的权限基础 二:shiro 认证

    认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一. ...

  4. 转:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法、shiro认证与shiro授权

    原文地址:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法.shiro认证与shiro授权 以下是部分内容,具体见原文. shiro介绍 什么是shiro shiro是Apache ...

  5. 将 Shiro 作为应用的权限基础 三:基于注解实现的授权认证过程

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限等等. 一.用户权限模型 为实现一个较为灵活的用户权限数据模 ...

  6. 1、 Shiro框架:认证,授权(验权 2. Shiro框架实现权限控制方式:

    1. Shiro框架:认证,授权(验权) a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------> ...

  7. 业务逻辑:五、完成认证用户的动态授权功能 六、完成Shiro整合Ehcache缓存权限数据

    一. 完成认证用户的动态授权功能 提示:根据当前认证用户查询数据库,获取其对应的权限,为其授权 操作步骤: 在realm的授权方法中通过使用principals对象获取到当前登录用户 创建一个授权信息 ...

  8. 第三章 授权——《跟我学Shiro》

    转发地址:https://www.iteye.com/blog/jinnianshilongnian-2020017 目录贴:跟我学Shiro目录贴 授权,也叫访问控制,即在应用中控制谁能访问哪些资源 ...

  9. Shiro学习(3)授权

    授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等).在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permission).角 ...

随机推荐

  1. 牛客小白月赛1 A 简单题 【数学】

    题目链接 https://www.nowcoder.com/acm/contest/85/A 思路 这个 就是 E 但是 运算的时候 要保证 其精度 AC代码 #include <cstdio& ...

  2. python核心编程3-13

    3.13: 添加新功能. 将你上一个问题改造好的readNwriteTextFiles.py 增加一个新功能: 允许用户编辑一个已经存在的文本文件. 你可以使用任何方式,无论是一次编辑一行,还是一次编 ...

  3. Windows 7 比Windows XP 难用的功能

    Windows 7 的搜索功能做得实在难用,不仅慢,还经常搜不到文件(明明存在的文件却搜不到).相比Windows XP,这个功能差的太远了. Windows 7 的无线连网功能,即使设置为不要自动连 ...

  4. DELPHI-Delphi常用类型及定义单元

    DELPHI-Delphi常用类型及定义单元 Type Unit Date SysUtils DeleteFile SysUtils or Windows (different versions) D ...

  5. HBase启动后端口60010无法访问

    配置好HBase后,想从浏览器通过端口60010看下节点情况,但是提示无法访问 在服务器上netstat -natl|grep 60010 发现并没有60010端口 原来是因为HBase 1.0 之后 ...

  6. Hive报错 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D

    报错信息如下 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyn ...

  7. MySQL- 用Navicat通过隧道连接到远程数据库

    在企业中,为了安全地使用服务器,常常是用通过堡垒机才能连接到企业内部的服务器,当然也包括数据库. 于是我们时时需要通过堡垒机打隧道连到数据库,下面展示如何使用xshell用Navicat通过隧道连接到 ...

  8. C++(三)— 二维容器

    1.二维bool向量 vector<vector<bool>> dp(len, vector<bool>(len, false));

  9. iis_rewrite3突然无法使用(因为它过期啦)

    转自http://www.b1y.cn/post/216.html ISAPI_Rewrite3完全版会有45天的试用期,过期了需要99美元进行够买,网上有很多破解版的,方法如下: 1.先从官网下一个 ...

  10. Java钉钉开发_异常_01_error code:50002, error message:请求的员工userid不在授权范围内

    一.异常原因: 请求的员工不在 应用的可见范围内. 如下图,应用的可见范围只设置为了部分员工.所以导致此异常 二.异常解决 将员工添加进可见范围即可