IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringSecurity学习第二天 -> 正文阅读

[Java知识库]SpringSecurity学习第二天

SpringSecurity学习第二天

访问控制url匹配

在前面讲解了认证中所有常用配置,主要是对 http.formLogin() 进行操作。

而在配置类中 http.authorizeRequests() 主要是对url进行控制,也就是我们所说的授权(访问控制)在前面讲解了认证中所有常用配置,主要是对 http.formLogin() 进行操作。而在配置类中 http.authorizeRequests() 主要是对url进行控制,也就是我们所说的授权(访问控制)

http.authorizeRequests() 也支持连缀写法,总体公式为: url 匹配规则.权限控制方法 通过上面的公式可以有很多 url 匹配规则和很多权限控制方法。这些内容进行各种组合就形成了 Spring Security中的授权。在所有匹配规则中取所有规则的交集。配置顺序影响了之后授权效果,越是具体的应该放在前面,越 是笼统的应该放到后面。

anyRequest()

在表示匹配所有的请求。一般情况下此方法都会使用设置全部内容都需要进行认证。

antMatcher()

public C antMatchers(String… antPatterns)

参数是不定向参数,每个参数是一个 ant 表达式,用于匹配 URL规则。

规则如下:
? : 匹配一个字符
* :匹配 0 个或多个字符
** :匹配 0 个或多个目录

放行所有静态资源

.antMatchers("/static/**").permitAll() 

regexMatchers()

使用正则表达式进行匹配。和 antMatchers() 主要的区别就是参数, antMatchers() 参数是 ant 表达式, regexMatchers() 参数是正则表达式。

无论是 antMatchers() 还是 regexMatchers() 都具有两个参数的方法,其中第一个参数都是HttpMethod,表示请求方式,当设置了HttpMethod后表示只有设定的特定的请求方式才执行对应的权限设置。

.antMatchers(HttpMethod.GET,"/login.html").permitAll()

mvcMatchers()

mvcMatchers()适用于配置了 servletPath 的情况。 servletPath 就是所有的 URL 的统一前缀。在 SpringBoot 整合SpringMVC 的项目中可以在 application.properties 中添加下面内容设置 ServletPath

spring.mvc.servlet.path=/名称

在 Spring Security 的配置类中配置 .servletPath() 是 mvcMatchers()返回值特有的方法,antMatchers()和 regexMatchers()没有这个方法。在 servletPath() 中配置了 servletPath 后,mvcMatchers()直接写 SpringMVC 中@RequestMapping()中设置的路径即可。或者直接在前两个匹配器中加上项目路径

.mvcMatchers("/login.html").servletPath("/xxxx").permitAll()
.antMatchers("/xxxx/login.html").permitAll()

内置访问控制方法

Spring Security 匹配了 URL 后调用了 permitAll() 表示不需要认证,随意访问。在 Spring Security 中提供了多种内置控制。

  • permitAll() : permitAll()表示所匹配的 URL 任何人都允许访问。

  • authenticated() : authenticated()表示所匹配的 URL 都需要被认证才能访问。

  • anonymous() : anonymous()表示可以匿名访问匹配的URL。和permitAll()效果类似,只是设置为 anonymous()的 url 会执行 filter 链中

  • denyAll() : denyAll()表示所匹配的 URL 都不允许被访问。

  • rememberMe() : 被“remember me”的用户允许访问

  • fullyAuthenticated() : 如果用户不是被 remember me 的,才可以访问。


角色权限判断

除了之前讲解的内置权限控制。Spring Security 中还支持很多其他权限控制。这些方法一般都用于用 户已经被认证后,判断用户是否具有特定的要求。

  • hasAuthority(String)判断用户是否具有特定的权限,用户的权限是在自定义登录逻辑中创建 User 对象时指定的hasAnyAuthority(String …)则匹配多个

    在配置类中通过 hasAuthority(“admin”)设置具有 admin 权限时才能访问。例子中admin和normal 就是用户的权限。权限 严格区分大小写。

    AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal”)                     
    
    .antMatchers("/main1.html").hasAuthority("admin")
    
  • hasRole(String) /hasAnyRole(String …): 如果用户具备给定角色就允许访问。否则出现 403

参数取值来源于自定义登录逻辑UserDetailsService实现类中创建User对象时给User赋予的授权在给用户赋予角色时角色需要以:ROLE_开头,后面添加角色名称。例如:ROLE_abc其中abc是角色名,ROLE_是固定的字符开头使用hasRole()时参数也只写 abc 即可。否则启动报错。

return new User("admin",password, AuthorityUtils.
commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc,/main.html"));}
  • hasIpAddress(String) 如果请求是指定的 IP 就运行访问。
.antMatchers("/main1.html").hasIpAddress("127.0.0.1")

自定义403处理方案

spingSeccurity自带的403界面应当被替换,Spring Security 支持自定义权限受限。当用户试图访问无权限资源时会403

新建类实现 AccessDeniedHandler

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.setContentType("application/json;charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write("{\"status\":\"403\",\"msg\":\"权限不足,请联系管理员\"}");
        writer.flush();//把数据从缓存区输出输出流
        writer.close();
    }
}

修改配置类

配置类中重点添加异常处理器。设置访问受限后交给哪个对象进行处理。
myAccessDeniedHandler 是在配置类中进行自动注入的。

 @Autowired
 private MyAccessDeniedHandler myAccessDeniedHandler;

http.exceptionHandling()
        .accessDeniedHandler(myAccessDeniedHandler);

基于表达式的访问控制

之前学习的登录用户权限判断实际上底层实现都是调用access(表达式),可以通过 access() 实现和之前学习的权限控制完成相同的功能。

.antMatchers("/main1.html").access("hasAnyAuthority('admin,Admin')")
.antMatchers("/main1.html").hasAnyAuthority("admin","Admin")

使用自定义方法

虽然这里面已经包含了很多的表达式(方法)但是在实际项目中很有可能出现需要自己自定义逻辑的情况.判断登录用户是否具有访问当前 URL 权限。

新建接口及实现类

public interface MyService {
    boolean hasPermission(HttpServletRequest request, Authentication authentication);
}
@Service
public class MyServiceImpl implements MyService {
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        String uri = request.getRequestURI();
        Object principal = authentication.getPrincipal();
        if(principal instanceof UserDetails){//怎么这两个联系起来了
            UserDetails userDetails = (UserDetails) principal;
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
            return authorities.contains(new SimpleGrantedAuthority(uri));
        }
        return false;
    }
}

修改配置类

在 access 中通过@bean的id名.方法(参数)的形式进行调用配置类中修改如下:

.anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");
//request我不知道为什么是这个对象名,而不能是htppservletrequest

基于注解的访问控制

在 Spring Security 中提供了一些访问控制的注解。这些注解都是默认是都不可用的,需要通过@EnableGlobalMethodSecurity 进行开启后使用。注解可以写到 Service 接口或方法上,也可以写到 Controller或 Controller 的方法上。通常情况下 都是写在控制器方法上的,控制接口URL是否允许被访问。

开启注解(在启动类 , 也可以在配置类等能够扫描的类上添加)

@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}
  • @Secured

    @Secured 是专门用于判断是否具有角色的。能写在方法或类上。参数要以 ROLE_开头。比如在控制器方法上添加@Secured 注解。也可以传入多个角色,参数是数组类型

    @Secured("ROLE_abc")
    @RequestMapping("/toMain")
    public String toMain(){
       return "redirect:/main.html";
    }
    
  • @PreAuthorize/@PostAuthorize: @PreAuthorize 和@PostAuthorize 都是方法或类级别注解。也需要去配置类中开启注解

    @PreAuthorize 表示访问方法或类在执行之前先判断权限,大多情况下都是使用这个注解,注解
    的参数和access()方法参数取值相同,都是权限表达式。
    @PostAuthorize 表示方法或类执行结束后判断权限,此注解很少被使用到。
    
    @PreAuthorize("hasRole('ROLE_abc')")//可以role可有可无
    @RequestMapping("/toMain")
    public String toMain(){
       return "redirect:/main.html";
    }
    

    拓展:@Secured和@PreAuthorize在Spring Security 3中有什么区别?

    如果你只想在用户具有Role1和Role2的情况下执行某些操作,则必须使用@PreAuthorize,而@Secured中数组元素则是或的关系无法完成共有两角色的限定

    @PreAuthorize("hasRole('ROLE_role1') and hasRole('ROLE_role2')")
    
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 13:57:03  更:2021-09-27 13:58:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:33:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码