Spring Boot 集成 Spring Security (1)

导读:本篇文章讲解 Spring Boot 集成 Spring Security (1),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

​ Spring Security是一款基于Spring的安全框架,主要包含认证和授权两大安全模块,和另外一款流行的安全框架Apache Shiro相比,它拥有更为强大的功能。Spring Security也可以轻松的自定义扩展以满足各种需求,并且对常见的Web安全攻击提供了防护支持。如果你的Web框架选择的是Spring,那么在安全方面Spring Security会是一个不错的选择。

​ 这里我们使用Spring Boot来集成Spring Security。

1. 开启Spring Security

​ 创建一个Spring Boot项目,然后引入spring-boot-starter-security:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

​ 接下来我们创建一个对外接口 /hello 服务:

@RestController
public class TestController {
    @GetMapping("hello")
    public String hello() {
        return "hello spring security";
    }
}

​ 这时候我们直接启动项目,访问http://localhost:8080/hello,可看到页面弹出了个表单认证框:

image-20220422161648045

​ 默认的用户名为user,密码由Sping Security自动生成,回到IDE的控制台,可以找到密码信息:

Using generated security password: 960ab494-f430-4f48-bbac-184997775110

​ 输入用户名user,密码960ab494-f430-4f48-bbac-184997775110后,我们便可以成功访问/hello接口。

​ 当输入凭证错误时,页面上将显示错误信息:

image-20220422162719784

2. 基于 HTTP Basic 认证

​ 我们可以通过一些配置将基于表单的认证修改为基于HTTP Basic的认证方式。

​ 创建一个配置类SecurityConfig继承org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter这个抽象类并重写configure(HttpSecurity http)方法。WebSecurityConfigurerAdapter是由Spring Security提供的Web应用安全配置的适配器:

​ 记得使用@Configuration注解,将其交给Spring管理。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //http.formLogin() // 表单方式
        http.httpBasic() // HTTP Basic方式
                .and()
                .authorizeRequests() // 授权配置
                .anyRequest()  // 所有请求
                .authenticated(); // 都需要认证
    }
}

​ Spring Security提供了这种链式的方法调用。上面配置指定了认证方式为HTTP Basic,并且所有请求都需要进行认证。这时候我们重启项目,再次访问http://localhost:8080/hello,可以看到认证方式已经是HTTP Basic的方式了:

image-20220422162857151

3. 基本原理

​ 上面我们开启了一个最简单的Spring Security安全配置,下面我们来了解下Spring Security的基本原理。通过上面的的配置,代码的执行过程可以简化为下图表示:

image-20220422162937987

​ 如上图所示,Spring Security包含了众多的过滤器,这些过滤器形成了一条链,所有请求都必须通过这些过滤器后才能成功访问到资源。其中UsernamePasswordAuthenticationFilter过滤器用于处理基于表单方式的登录认证,而BasicAuthenticationFilter用于处理基于HTTP Basic方式的登录验证,后面还可能包含一系列别的过滤器(可以通过相应配置开启)。在过滤器链的末尾是一个名为FilterSecurityInterceptor的拦截器,用于判断当前请求身份认证是否成功,是否有相应的权限,当身份认证失败或者权限不足的时候便会抛出相应的异常。ExceptionTranslateFilter捕获并处理,所以我们在ExceptionTranslateFilter过滤器用于处理了FilterSecurityInterceptor抛出的异常并进行处理,比如需要身份认证时将请求重定向到相应的认证页面,当认证失败或者权限不足时返回相应的提示信息。

​ 下面我们通过debug来验证这个过程(登录方式改回表单的方式)。

​ 我们在/hello服务上打个断点:

image-20220422163310547

​ 在FilterSecurityInterceptor的invoke方法的super.beforeInvocation上打个断点:

image-20220422163341371

​ 当这行代码执行通过后,便可以调用下一行的doFilter方法来真正调用/hello服务,否则将抛出相应的异常。

​ 当FilterSecurityInterceptor抛出异常时,异常将由ExceptionTranslateFilter捕获并处理,所以我们在ExceptionTranslationFilterdoFilter方法catch代码块第一行打个断点:

image-20220422163841617

​ 我们待会模拟的是用户未登录直接访问/hello,所以应该是抛出用户未认证的异常,所以接下来应该跳转到UsernamePasswordAuthenticationFilter处理表单方式的用户认证。在UsernamePasswordAuthenticationFilterattemptAuthentication方法上打个断点:

image-20220422164042143

​ 准备完毕后,我们启动项目,然后访问http://localhost:8080/hello,代码直接跳转到FilterSecurityInteceptor的断点上:

image-20220422164240320

​ 往下执行,因为当前请求没有经过身份认证,所以将抛出异常并被ExceptionTranslationFilter捕获:

image-20220422164300274

​ 捕获异常后重定向到登录表单登录页面,当我们在表单登录页面输入信息点login后,代码跳转到UsernamePasswordAuthenticationFilter过滤器的attemptAuthentication方法上:

image-20220422164447114

​ 判断用户名和密码是否正确之后,代码又跳回FilterSecurityInterceptorbeforeInvocation方法执行上:

image-20220422164505026

​ 当认证通过时,FilterSecurityInterceptor代码往下执行doFilter,然后代码最终跳转到/hello上:

image-20220422164527454

​ 最终浏览器页面将显示hello spring security信息。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/16712.html

(0)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!