个人网站建设方案书例文,php医疗网站咨询源码,苏州百度,电脑网站推荐授权
什么是权限管理 权限管理核心概念 SpringSecurity权限管理策略 基于URL地址的权限管理 基于方法的权限管理
一、权限管理 二、授权核心概念
在认证的过程成功之后会将当前用户登录信息保存到Authentication对象中#xff0c;Authentication对象中有一个getAuthorities…授权
什么是权限管理 权限管理核心概念 SpringSecurity权限管理策略 基于URL地址的权限管理 基于方法的权限管理
一、权限管理 二、授权核心概念
在认证的过程成功之后会将当前用户登录信息保存到Authentication对象中Authentication对象中有一个getAuthorities()方法用来返回当前登录用户具备的权限信息。该方法返回值是Collectionsextends GrantedAuthority当需要进行权限判断时就根据集合返回权限信息调用对应方法进行判断。
public interface Authentication extends Principal, Serializable {Collection? extends GrantedAuthority getAuthorities();// 省略
}那么针对返回值应该如何理解是权限还是角色 RBAC(Role/Resource Base Access Controll) 针对收取按可以是基于角色权限管理和基于资源权限管理从设计层面来说角色和权限是俩个不同的东西。权限是一些具体的操作角色是一些权限的集合。egREAD_BOOK和ROLE_ADMIN是完全不同的。因此至于返回值是什么应当取决于业务的设计。
基于角色权限设计用户角色资源三者关系返回就是用户的角色。基于资源权限设计用户权限资源三者关系返回就是用户的权限。基于角色和资源权限设计用户角色权限资源的关系返回统称为用户的权限。 这里统称为权限是因为代码层面来说权限和角色没有太大的不同都是权限。其在SpringSecurity中处理方式也基本相同。唯一的区别是会自动给角色多加一个ROLE_前缀。
三、两种权限管理策略
SpringSecurity主要提供俩种权限管理策略 可以访问系统中的那些资源URL、Method
基于过滤器(URL)的权限管理FilterSecurityInterceptor 基于过滤器的权限管理主要用来拦截HTTP请求拦截下来后根据http请求地址进行权限校验。基于AOP(Method)的权限管理MethodSecurityInterceptor 基于AOP权限管理主要用来处理方法级别的权限问题。当需要调用某一方法时通过aop将操作拦截然后判断用户是否具备相关权限。
1、基于URL权限管理
1.1 案例
编写HiController
RestController
public class HiController {RequestMapping(/)public String home() {return h1HI SPRING SECURITY/hi;}RequestMapping(/admin)public String admin() {return h1HI SPRING ADMIN/hi;}RequestMapping(/user)public String user() {return h1HI USER/hi;}RequestMapping(/getInfo)public Authentication getInfo() {return SecurityContextHolder.getContext().getAuthentication();}
}编写SecurityConfig
EnableWebSecurity
public class SecurityConfig {Beanpublic UserDetailsService userDetailsService(){InMemoryUserDetailsManager manager new InMemoryUserDetailsManager();manager.createUser(User.withUsername(root).password({noop}123).roles(ADMIN,USER).build());manager.createUser(User.withUsername(whx).password({noop}123).roles(USER).build());manager.createUser(User.withUsername(dy).password({noop}123).authorities(READ_INFO).build());return manager;}Beanpublic SecurityFilterChain configure(HttpSecurity http) throws Exception {http.authorizeHttpRequests(req - {req.mvcMatchers(/admin).hasRole(ADMIN);req.mvcMatchers(/user).hasRole(USER);req.mvcMatchers(/getInfo).hasAuthority(READ_INFO);req.anyRequest().authenticated();});http.formLogin();http.csrf().disable();return http.build();}
}1.2 权限表达式
public interface SecurityExpressionOperations {// 获取用户权限信息Authentication getAuthentication();// 当前用户是否具备指定权限boolean hasAuthority(String authority);// 当前用户是否具备指定权限中的任意一个boolean hasAnyAuthority(String... authorities);// 当前用户是否具备指定角色boolean hasRole(String role);// 当前用户是否具备指定角色任意一个boolean hasAnyRole(String... roles);// 放行所有请求boolean permitAll();// 拒绝所有请求boolean denyAll();// 当前用户是否匿名用户boolean isAnonymous();// 当前用户是否已经认证成功boolean isAuthenticated();// 当前用户是否通过RememberMe记住我自动登录boolean isRememberMe();// 当前用户是否既不是宁ing用户也不是通过rememberMe自动登录boolean isFullyAuthenticated();// 当前用户是否具备指定目标的指定权限信息boolean hasPermission(Object target, Object permission);// 当前用户是否具备指定目标的指定权限信息boolean hasPermission(Object targetId, String targetType, Object permission);
}1.3 URL匹配规则antMatchers、mvcMatchers、regexMatchers
antMatchers和mvcMatchers的区别在于mvcMatchers更加强大通用而regexMatchers的好处是支持正则表达式。
2. 基于方法的权限管理
基于方法的权限管理通过AOP来实现SpringSecurity中通过MethodSecurityInterceptor来提供相关实现。不同在于FilterSecurityInterceptor只是在请求之前进行前置处理MethodSecurityInterceptor除了前置处理之外还可以进行后置处理。前置处理就是在请求之前判断是否具有响应权限而后置处理则是对方法执行结果进行二次过滤。前置处理和后置处理对应了不同的实现类。
EnableGlobalMethodSecurity
EnableGlobalMethodSecurity注解用来开启权限用法如下
EnableWebSecurity
// 开启全局方法权限配置仅可能的显示配置三个属性为true
EnableGlobalMethodSecurity(prePostEnabled true,securedEnabled true,jsr250Enabled true)
public class SecurityConfig2 {prePostEnabled 开启SpringSecurity提供的四个权限注解PostAuthorize、PostFilter、PreAuthorize、PreFiltersecuredEnabled开启SpringSecurity提供的Secured注解支持该注解不支持权限表达式jsr250Enabled开启JSR-250提供的注解主要是DenyAll、PermitAll、RolesAll同样的这些注解也不支持权限表达式。
注解含义PostAuthorize在目标方法执行之后进行权限校验PostFilter在目标方法执行之后对返回结果进行过滤PreAuthorize在目标方法执行之前进行权限校验PreFilter在目标方法执行之前对方法参数进行过滤Secured访问目标方法必须具备对应的角色DenyAll拒绝所有访问PermitAll允许所有访问RolesAll访问目标方法必须具备对应的角色
这些基于方法的权限管理相关的注解由于后四个不常用一般来说只需要设置prePostEnabled true即可 权限表达式例子hasRole(admin)
案例
编写SecurityConfig
EnableWebSecurity
EnableGlobalMethodSecurity(prePostEnabled true,securedEnabled true,jsr250Enabled true)
public class SecurityConfig2 {Beanpublic UserDetailsService userDetailsService(){InMemoryUserDetailsManager manager new InMemoryUserDetailsManager();manager.createUser(User.withUsername(root).password({noop}123).roles(ADMIN,USER).build());manager.createUser(User.withUsername(whx).password({noop}123).roles(USER).build());manager.createUser(User.withUsername(dy).password({noop}123).authorities(READ_INFO).build());return manager;}Beanpublic SecurityFilterChain configure(HttpSecurity http) throws Exception {http.authorizeHttpRequests(req - {req.anyRequest().authenticated();});http.formLogin();http.csrf().disable();return http.build();}
}编写T2Controller
RestController
RequestMapping(t2)
public class T2Controller {PreAuthorize(hasRole(ADMIN) and authentication.name root)RequestMapping(/)public String home() {return h1HI SPRING SECURITY/hi;}// http://localhost:8888/t2/name?namerootPreAuthorize(authentication.name #name)RequestMapping(/name)public String admin(String name) {return h1HI SPRING name /hi;}// [ { id:1,username:huathy },
// { id:2,username:dy } ]PreFilter(value filterObject.id%2 ! 0, filterTarget users) //filterTarget参数必须是集合类型RequestMapping(/add)public ListUser add(RequestBody ListUser users) {ListUser result new ArrayList();for (User user : users) {result.add(User.build(user.getId(), user.getUsername()));}return result;}// http://localhost:8888/t2/userId?id1PostAuthorize(returnObject.id 1)RequestMapping(/userId)public User userId(Integer id) {User user User.build(id, HUATHY);return user;}PostFilter(filterObject.id%2 0)RequestMapping(/lists)public ListUser getAllUser() {ListUser users new ArrayList();for (int i 0; i 10; i) {users.add(User.build(i, 嘻嘻 i));}return users;}PreAuthorize(hasAuthority(READ_INFO))RequestMapping(/getInfo)public Object getInfo() {return SecurityContextHolder.getContext().getAuthentication().getPrincipal();}/* 以下是不常用的 只做演示 */// 具备其中一个即可Secured({ROLE_ADMIN, ROLE_USER})RequestMapping(/secured)public String secured() {return h1HUATHY/h1;}PermitAllRequestMapping(permitAll)public String permitAll() {return h1permitAll/h1;}DenyAllRequestMapping(DenyAll)public String DenyAll() {return h1DenyAll/h1;}RolesAllowed({ROLE_ADMIN, ROLE_USER})// 具备其中一个即可RequestMapping(rolesAllowed)public String rolesAllowed() {return h1rolesAllowed/h1;}
}四、授权的原理分析 ConfigAttribute在springsecurity中用户请求一个资源通常是一个接口或者Java方法需要的角色会被封装成一个ConfigAttribute对象在ConfigAttribute中只有一个getAttribute方法该方法赶回一个String字符串角色名称。一般的角色名称都带有一个ROLE_前缀投票器AccessDecisionVoter所做的事情其实就是比较用户所具有的角色和请求某个资源所需要的ConfigAttribute之间的关系。AccessDecisionVoter和AccessDecisionManager都有众多实现类。在AccessDecisionManager中会挨个遍历AccessDecisionVoter进而决定是否允许用户方法因而AccessDecisionVoter和AccessDecisionManager俩者关系类似于AuthenticationProvicder和ProviderManager的关系。
授权实战—权限模型说明1
在前面的案例中我们配置的URL拦截规则和URL所需要的权限都是通过代码配置的这样过于死板。如果需要动态的管理权限规则我们可以将URL拦截规则和访问URL所需的权限都保存到数据库中这样在不修改代码的情况下只需要吸怪数据库即可对权限进行调整。 用户 --用户角色表-- 角色 --角色菜单表-- 菜单
库表设计
create table menu
(id int auto_incrementprimary key,pattern varchar(100) null
)comment 菜单表;create table menu_role
(id int auto_incrementprimary key,rid int not null,mid int not null
);create table role
(id int auto_incrementprimary key,name varchar(255) null,name_cn varchar(255) null
);create table user
(id int auto_incrementprimary key,username varchar(255) null,password varchar(255) null,accountNonExpired int(1) null,accountNunLocked int(1) null,credentialsNonExpired int(1) null,enable int(1) null
);create table user_role
(id int auto_incrementprimary key,uid int null,rid int null
);数据
insert into role values (101,superadmin,超级管理员);
insert into role values (102,admin,管理员);
insert into role values (103,user,普通用户);insert into user values (1001,huathy,{noop}123,0,0,0,0);
insert into user values (1002,whx,{noop}123,0,0,0,0);
insert into user values (1003,dy,{noop}123,0,0,0,0);insert into user_role values (0,1001,101);
insert into user_role values (0,1002,102);
insert into user_role values (0,1003,103);insert into menu values (1,/admin/**);
insert into menu values (2,/user/**);
insert into menu values (3,/guest/**);insert into menu_role values (0,101,1);
insert into menu_role values (0,102,2);
insert into menu_role values (0,103,3);实现
本文只展示了核心代码详细的参考附录1。
1. MyUserDetailsService
实现自定义UserDetailsService从数据库获取用户信息。
Component
public class MyUserDetailsService implements UserDetailsService {Autowiredprivate UserMapper userMapper;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user userMapper.getUserByUname(username);if (ObjectUtils.isEmpty(user)) {throw new UsernameNotFoundException(用户名不正确);}ListRole roles userMapper.getRolesByUid(user.getId());user.setRoles(roles);return user;}
}2. 编写SecurityCfg配置来自定义URL权限处理。
EnableWebSecurity
public class SecurityCfg {Autowiredprivate CustomerSecurityMetadataSource customerSecurityMetadataSource;Beanpublic SecurityFilterChain configure(HttpSecurity http) throws Exception {// 1. 获取工厂对象ApplicationContext applicationContext http.getSharedObject(ApplicationContext.class);// 2. 设置自定义URL权限处理http.apply(new UrlAuthorizationConfigurer(applicationContext)).withObjectPostProcessor(new ObjectPostProcessorFilterSecurityInterceptor() {Overridepublic O extends FilterSecurityInterceptor O postProcess(O object) {object.setSecurityMetadataSource(customerSecurityMetadataSource);// 是否拒绝公共资源的访问object.setRejectPublicInvocations(false);return object;}});http.authorizeHttpRequests().anyRequest().authenticated();http.formLogin();http.csrf().disable();return http.build();}
}3. 编写自定义权限元数据CustomerSecurityMetadataSource
需要注意的是此类中的SecurityConfig是springSecurity官方的SecurityConfig。
Component
public class CustomerSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {AutowiredMenuService menuService;// 用来做路径比对AntPathMatcher antPathMatcher new AntPathMatcher();/*** 自定义动态资源权限元数据信息** param object* return* throws IllegalArgumentException*/Overridepublic CollectionConfigAttribute getAttributes(Object object) throws IllegalArgumentException {// 根据当前请求对象获取URIString requestURI ((FilterInvocation) object).getRequest().getRequestURI();// 查询菜单对象ListMenu allMenu menuService.getList(null);for (Menu menu : allMenu) {if (antPathMatcher.match(menu.getPattern(), requestURI)) {String[] roles new String[menu.getRoles().size()];for (int i 0; i menu.getRoles().size(); i) {roles[i] ROLE_ menu.getRoles().get(i).getName();}return SecurityConfig.createList(roles);}}return null;}Overridepublic CollectionConfigAttribute getAllConfigAttributes() {return null;}Overridepublic boolean supports(Class? clazz) {return FilterInvocation.class.isAssignableFrom(clazz);}
}4. MenuService
Service
public class MenuService {Autowiredprivate MenuMapper menuMapper;Autowiredprivate MenuRoleMapper menuRoleMapper;public ListMenu getList(Object o) {ListMenu menus menuMapper.selectList(null);for (Menu menu : menus) {ListRole roles menuRoleMapper.getAllMenuRoles(menu.getId());if (!CollectionUtils.isEmpty(roles)) {menu.setRoles(roles);}}return menus;}
}踩坑
这里有点坑的地方就是SpringSecurity会给角色的权限自动加上ROLE_即便我加了前缀他还是会自动加一次。这导致了这里equls的时候匹配失败。所以这里我们取消数据库中的前缀这样查询出来的用户的角色是不带前缀的egADMIN而我们在查询菜单的角色的构建CustomerSecurityMetadataSource元数据的时候给手动加上前缀ROLE_就像这样子roles[i] ROLE_ menu.getRoles().get(i).getName();。
附录
本文涉及代码部分https://gitee.com/huathy/study-all/tree/master/spring_security_study 文章转载自: http://www.morning.bmyrl.cn.gov.cn.bmyrl.cn http://www.morning.mbpzw.cn.gov.cn.mbpzw.cn http://www.morning.sjsfw.cn.gov.cn.sjsfw.cn http://www.morning.npmx.cn.gov.cn.npmx.cn http://www.morning.xkjqg.cn.gov.cn.xkjqg.cn http://www.morning.tkzqw.cn.gov.cn.tkzqw.cn http://www.morning.wxlzr.cn.gov.cn.wxlzr.cn http://www.morning.osshjj.cn.gov.cn.osshjj.cn http://www.morning.rmfh.cn.gov.cn.rmfh.cn http://www.morning.ptqds.cn.gov.cn.ptqds.cn http://www.morning.xlxmy.cn.gov.cn.xlxmy.cn http://www.morning.bpmnj.cn.gov.cn.bpmnj.cn http://www.morning.wjhnx.cn.gov.cn.wjhnx.cn http://www.morning.tjpmf.cn.gov.cn.tjpmf.cn http://www.morning.hcqpc.cn.gov.cn.hcqpc.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.lveyue.com.gov.cn.lveyue.com http://www.morning.wjwfj.cn.gov.cn.wjwfj.cn http://www.morning.hlwzd.cn.gov.cn.hlwzd.cn http://www.morning.gcdzp.cn.gov.cn.gcdzp.cn http://www.morning.xsgxp.cn.gov.cn.xsgxp.cn http://www.morning.xpmwt.cn.gov.cn.xpmwt.cn http://www.morning.lprfk.cn.gov.cn.lprfk.cn http://www.morning.wchcx.cn.gov.cn.wchcx.cn http://www.morning.hgsmz.cn.gov.cn.hgsmz.cn http://www.morning.drgmr.cn.gov.cn.drgmr.cn http://www.morning.gyfwy.cn.gov.cn.gyfwy.cn http://www.morning.gfpyy.cn.gov.cn.gfpyy.cn http://www.morning.qfqld.cn.gov.cn.qfqld.cn http://www.morning.gyfhk.cn.gov.cn.gyfhk.cn http://www.morning.brcdf.cn.gov.cn.brcdf.cn http://www.morning.cbqqz.cn.gov.cn.cbqqz.cn http://www.morning.ljcf.cn.gov.cn.ljcf.cn http://www.morning.bnqcm.cn.gov.cn.bnqcm.cn http://www.morning.ydflc.cn.gov.cn.ydflc.cn http://www.morning.rbbgh.cn.gov.cn.rbbgh.cn http://www.morning.bkjhx.cn.gov.cn.bkjhx.cn http://www.morning.zwyuan.com.gov.cn.zwyuan.com http://www.morning.ltkms.cn.gov.cn.ltkms.cn http://www.morning.tfkqc.cn.gov.cn.tfkqc.cn http://www.morning.ssqwr.cn.gov.cn.ssqwr.cn http://www.morning.qlrtd.cn.gov.cn.qlrtd.cn http://www.morning.sjli222.cn.gov.cn.sjli222.cn http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.sffwz.cn.gov.cn.sffwz.cn http://www.morning.csjps.cn.gov.cn.csjps.cn http://www.morning.srnth.cn.gov.cn.srnth.cn http://www.morning.zqfjn.cn.gov.cn.zqfjn.cn http://www.morning.jljwk.cn.gov.cn.jljwk.cn http://www.morning.xnhnl.cn.gov.cn.xnhnl.cn http://www.morning.rmfwh.cn.gov.cn.rmfwh.cn http://www.morning.ymqrc.cn.gov.cn.ymqrc.cn http://www.morning.dlgjdg.cn.gov.cn.dlgjdg.cn http://www.morning.rgzc.cn.gov.cn.rgzc.cn http://www.morning.kklwz.cn.gov.cn.kklwz.cn http://www.morning.gnkbf.cn.gov.cn.gnkbf.cn http://www.morning.tgqzp.cn.gov.cn.tgqzp.cn http://www.morning.wprxm.cn.gov.cn.wprxm.cn http://www.morning.kmwbq.cn.gov.cn.kmwbq.cn http://www.morning.bttph.cn.gov.cn.bttph.cn http://www.morning.hcgbm.cn.gov.cn.hcgbm.cn http://www.morning.cnprt.cn.gov.cn.cnprt.cn http://www.morning.rkqzx.cn.gov.cn.rkqzx.cn http://www.morning.rbqlw.cn.gov.cn.rbqlw.cn http://www.morning.gthwr.cn.gov.cn.gthwr.cn http://www.morning.fslrx.cn.gov.cn.fslrx.cn http://www.morning.mlbdr.cn.gov.cn.mlbdr.cn http://www.morning.bsrqy.cn.gov.cn.bsrqy.cn http://www.morning.xsszn.cn.gov.cn.xsszn.cn http://www.morning.wfbnp.cn.gov.cn.wfbnp.cn http://www.morning.zbpqq.cn.gov.cn.zbpqq.cn http://www.morning.zcrjq.cn.gov.cn.zcrjq.cn http://www.morning.kvzvoew.cn.gov.cn.kvzvoew.cn http://www.morning.xsrnr.cn.gov.cn.xsrnr.cn http://www.morning.dmtld.cn.gov.cn.dmtld.cn http://www.morning.gcfrt.cn.gov.cn.gcfrt.cn http://www.morning.kgxrq.cn.gov.cn.kgxrq.cn http://www.morning.ljbpk.cn.gov.cn.ljbpk.cn http://www.morning.bpmdx.cn.gov.cn.bpmdx.cn http://www.morning.lkfsk.cn.gov.cn.lkfsk.cn