当前位置: 首页 > news >正文

个人网站创建/企业文化理念

个人网站创建,企业文化理念,cn.wordpress,如何在网站上添加qqSpring Security---授权操作详解1.授权2.准备测试用户3.准备测试接口4.配置5.启动测试角色继承1.授权 所谓的授权,就是用户如果要访问某一个资源,我们要去检查用户是否具备这样的权限,如果具备就允许访问,如果不具备,…

Spring Security---授权操作详解

  • 1.授权
  • 2.准备测试用户
  • 3.准备测试接口
    • 4.配置
    • 5.启动测试
    • 角色继承


1.授权

所谓的授权,就是用户如果要访问某一个资源,我们要去检查用户是否具备这样的权限,如果具备就允许访问,如果不具备,则不允许访问。

2.准备测试用户

因为我们现在还没有连接数据库,所以测试用户还是基于内存来配置。

基于内存配置测试用户,我们有两种方式,第一种就是前面几篇文章用的配置方式,如下:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("dhy").password("123").roles("admin").and().withUser("大忽悠").password("123").roles("user");
}

这是一种配置方式。

由于 Spring Security 支持多种数据源,例如内存、数据库、LDAP 等,这些不同来源的数据被共同封装成了一个 UserDetailService 接口,任何实现了该接口的对象都可以作为认证数据源。

因此我们还可以通过重写 WebSecurityConfigurerAdapter 中的 userDetailsService 方法来提供一个 UserDetailService 实例进而配置多个用户:

   @Beanprotected UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withUsername("dhy").password("123").roles("admin").build());manager.createUser(User.withUsername("大忽悠").password("123").roles("user").build());return manager;}

放入容器中后,会被自动使用

两种基于内存定义用户的方法,大家任选一个。


3.准备测试接口

测试用户准备好了,接下来我们准备三个测试接口。如下:

@RestController
public class HelloController {@GetMapping("/hello")public String hello() {return "hello";}@GetMapping("/admin/hello")public String admin() {return "admin";}@GetMapping("/user/hello")public String user() {return "user";}
}

这三个测试接口,我们的规划是这样的:

  • /hello 是任何人都可以访问的接口
  • /admin/hello 是具有 admin 身份的人才能访问的接口
  • /user/hello 是具有 user 身份的人才能访问的接口
  • 所有 user 能够访问的资源,admin 都能够访问

注意第四条规范意味着所有具备 admin 身份的人自动具备 user 身份。


4.配置

接下来我们来配置权限的拦截规则,在 Spring Security 的 configure(HttpSecurity http) 方法中,代码如下:

http.authorizeRequests().antMatchers("/admin/**").hasRole("admin").antMatchers("/user/**").hasRole("user").anyRequest().authenticated().and()......

这里的匹配规则我们采用了 Ant 风格的路径匹配符,Ant 风格的路径匹配符在 Spring 家族中使用非常广泛,它的匹配规则也非常简单:

通配符含义
**匹配多层路径
*匹配单层路径
?匹配任意单个字符

上面配置的含义是:

  • 如果请求路径满足 /admin/** 格式,则用户需要具备 admin 角色。
  • 如果请求路径满足 /user/** 格式,则用户需要具备 user 角色。
  • 剩余的其他格式的请求路径,只需要认证(登录)后就可以访问。

注意代码中配置的三条规则的顺序非常重要,和 Shiro 类似,Spring Security 在匹配的时候也是按照从上往下的顺序来匹配,一旦匹配到了就不继续匹配了,所以拦截规则的顺序不能写错。

另一方面,如果你强制将 anyRequest 配置在 antMatchers 前面,像下面这样:

http.authorizeRequests().anyRequest().authenticated().antMatchers("/admin/**").hasRole("admin").antMatchers("/user/**").hasRole("user").and()

此时项目在启动的时候,就会报错,会提示不能在 anyRequest 之后添加 antMatchers

在这里插入图片描述
这从语义上很好理解,anyRequest 已经包含了其他请求了,在它之后如果还配置其他请求也没有任何意义。

从语义上理解,anyRequest 应该放在最后,表示除了前面拦截规则之外,剩下的请求要如何处理。

在拦截规则的配置类 AbstractRequestMatcherRegistry 中,我们可以看到如下一些代码(部分源码):

public abstract class AbstractRequestMatcherRegistry<C> {private boolean anyRequestConfigured = false;public C anyRequest() {Assert.state(!this.anyRequestConfigured, "Can't configure anyRequest after itself");this.anyRequestConfigured = true;return configurer;}public C antMatchers(HttpMethod method, String... antPatterns) {Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");return chainRequestMatchers(RequestMatchers.antMatchers(method, antPatterns));}public C antMatchers(String... antPatterns) {Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");return chainRequestMatchers(RequestMatchers.antMatchers(antPatterns));}protected final List<MvcRequestMatcher> createMvcMatchers(HttpMethod method,String... mvcPatterns) {Assert.state(!this.anyRequestConfigured, "Can't configure mvcMatchers after anyRequest");return matchers;}public C regexMatchers(HttpMethod method, String... regexPatterns) {Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");return chainRequestMatchers(RequestMatchers.regexMatchers(method, regexPatterns));}public C regexMatchers(String... regexPatterns) {Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");return chainRequestMatchers(RequestMatchers.regexMatchers(regexPatterns));}public C requestMatchers(RequestMatcher... requestMatchers) {Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");return chainRequestMatchers(Arrays.asList(requestMatchers));}
}

从这段源码中,我们可以看到,在任何拦截规则之前(包括 anyRequest 自身),都会先判断 anyRequest 是否已经配置,如果已经配置,则会抛出异常,系统启动失败。

这样大家就理解了为什么 anyRequest 一定要放在最后。


5.启动测试

接下来,我们启动项目进行测试。

我们先通过大忽悠用户的账号访问:

登录成功后,分别访问 /hello,/admin/hello 以及 /user/hello 三个接口,其中:

  • /hello 因为登录后就可以访问,这个接口访问成功。
  • /admin/hello 需要 admin 身份,所以访问失败。
  • /user/hello 需要 user 身份,所以访问成功。

首先登录:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
访问admin身份可以访问的资源时,成功
在这里插入图片描述

当访问user身份才可以访问的资源时,会显示403,无权限
在这里插入图片描述


完整的配置:

public class SecurityConfig extends WebSecurityConfigurerAdapter {private ObjectMapper objectMapper=new ObjectMapper();@BeanPasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/js/**", "/css/**","/images/**");}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("dhy").password("123").roles("admin").and().withUser("大忽悠").password("123").roles("user");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("admin").antMatchers("/user/**").hasRole("user").anyRequest().authenticated().and().formLogin()//注意放行请求,否则会404.loginPage("/login.html").permitAll().loginProcessingUrl("/login").permitAll().successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {httpServletResponse.setContentType("application/json;charset=UTF-8");httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));}}).permitAll().and().csrf().disable();}
}

角色继承

所有 user 能够访问的资源,admin 都能够访问,很明显我们目前的代码还不具备这样的功能。

要实现所有 user 能够访问的资源,admin 都能够访问,这涉及到另外一个知识点,叫做角色继承。

这在实际开发中非常有用。

上级可能具备下级的所有权限,如果使用角色继承,这个功能就很好实现,我们只需要在 SecurityConfig 中添加如下代码来配置角色继承关系即可:

@Bean
RoleHierarchy roleHierarchy() {RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();hierarchy.setHierarchy("ROLE_admin > ROLE_user");return hierarchy;
}

注意,在配置时,需要给角色手动加上 ROLE_ 前缀。上面的配置表示 ROLE_admin 自动具备 ROLE_user 的权限。

配置完成后,重启项目,此时我们发现 dhy 也能访问 /user/hello 这个接口了。

在这里插入图片描述

在这里插入图片描述


http://www.lbrq.cn/news/1294381.html

相关文章:

  • 网站开发定位/黑马it培训班出来现状
  • 国内最新重大新闻/指定关键词seo报价
  • 教育中介公司网站建设费用/网络营销的培训课程
  • 怎么让学生在网站上做问卷调查/百度收录入口在哪里
  • 高端网网站建设/网站推广营销运营方式
  • 求职网站开发多少钱/长春百度推广公司
  • 电商摄影/seo产品优化免费软件
  • crazyuncle WordPress/某网站seo诊断分析
  • html全部源码免费/北京seo优化诊断
  • 中山做网站优化/百度识图网页版 在线
  • 网站建设服务合同缴纳印花税吗/百度广告联盟怎么加入
  • php ajax网站开发/百度企业认证怎么认证
  • 医院建网站/百度收录api怎么提交
  • 中国建设银行江西分行网站首页/百度收录
  • 广州哪家做网站/长尾关键词挖掘工具
  • 做一家电商网站需要多少钱/企业网站模板 免费
  • 网站建设需求说明书/泉州搜索推广
  • 页面设计一般用什么软件/seo专业培训
  • 我司如何自己建设动态网站/关键词搜索引擎又称为
  • 信息课做网站的软件/seo咨询师
  • 做学校网站的目的是什么/恶意点击软件哪个好
  • 上海建筑工程股份有限公司/江西短视频seo搜索报价
  • 做的美食视频网站/百度推广可以自己开户吗
  • 澳门网站建设/免费学生网页制作成品代码
  • 酒店电子商务网站策划书/制作一个网站大概需要多少钱
  • 网站建设百度搜索到左边的图/网络营销管理
  • js网站建设/b站2020推广网站
  • 常德公司做网站/百度广告联盟平台的使用知识
  • 实验一html静态网站开发/百度上海总部
  • 直播视频网站如何做/营销管理制度范本
  • 2025最新版PyCharm for Mac统一版安装使用指南
  • USRP采集信号转换为时频图数据集
  • react-window 大数据列表和表格数据渲染组件之虚拟滚动
  • delphi disqlite3 操作sqlite
  • Lua:小巧而强大的脚本语言,游戏与嵌入式的秘密武器
  • UDP中的单播,多播,广播(代码实现)