目录
Spring Security 学习专栏
2. Spring Security 自定义认证管理器和讲解 (二)
一、简介
Spring Security 概述
在web应用开发中,安全无疑是十分重要的,选择Spring Security来保护web应用是一个非常好的选择。Spring Security 是Spring项目之中的一个安全模块,可以非常方便与Spring项目无缝集成。利用 Spring IoC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。特别是SpringBoot项目中加入Spring Security更是十分简单。本篇我们介绍Spring Security,以及Spring Security在web应用中的使用。
Spring Security 的核心功能主要包括
认证 :(你是谁)比如用户登入、系统授权访问
授权 :(你能干什么)当前用户有哪些资源可以访问
攻击防护 :(防止伪造身份)
其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
安全框架概述
什么是安全框架? 解决系统安全问题的框架。如果没有安全框架,我们需要手动处理每个资源的访问控制,非常麻烦。使用安全框架,我们可以通过配置的方式实现对资源的访问限制。
常用安全框架
- Spring Security:Spring家族一员。是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC , DI(控制反转Inversion of Control,DI:Dependency Injection 依赖注入)和 AOP(面向切面编程) 功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
- Apache Shiro:一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理。
历史
Spring Security 以“The Acegi Secutity System for Spring”的名字始于2003年年底。其前身为 acegi项目。起因是 Spring 开发者邮件列表中一个问题,有人提问是否考虑提供一个基于 Spring 的安全实现。限制于时间问题,开发出了一个简单的安全实现,但是并没有深入研究。几周后,Spring 社区中其他成员同样询问了安全问题,代码提供给了这些人。2004 年 1 月份已经有 20 人左右使用这个项目。随着更多人的加入,在 2004 年 3 月左右在 sourceforge 中建立了一个项目。在最开始并没有认证模块,所有的认证功能都是依赖容器完成的,而 acegi 则注重授权。但是随着更多人的使用,基于容器的认证就显现出了不足。acegi 中也加入了认证功能。大约 1 年后 acegi 成为 Spring子项目。在 2006 年 5 月发布了 acegi 1.0.0 版本。2007 年底 acegi 更名为Spring Security。
二、一个Spring Security的例子开始
1. pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- 实现对 Spring MVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 实现对 Spring Security 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
2. IndexController
@RestController
@RequestMapping("index")
public class IndexController {
@GetMapping("hello")
public String hello() {
return "Hello ,spring security !";
}
}
我们启动应用,默认端口是8080,那么当我们在浏览器访问的时候可以在浏览器看到如下界面。
http://127.0.0.1:8080/index/hello
我们可以得到一个页面,如下
说明Spring Security 已经起作用了,我们需要登陆才能访问,对我访问做了过滤拦截,我们可以查看下这个页面的源代码,是这样:
<html>
<head><title>Login Page</title></head>
<body onload='document.f.username.focus();'>
<h3>Login with Username and Password</h3>
<form name='f' action='/login' method='POST'>
<table>
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
<input name="_csrf" type="hidden" value="635780a5-6853-4fcd-ba14-77db85dbd8bd" />
</table>
</form>
</body>
</html>
上面的html中有个form ,其中 action="/login"
,这个/login
依然是Spring Security提供的。form表单提交了三个数据:
- username 用户名
- password 密码
- _csrf CSRF保护方面的内容,暂时先不展开解释
为了登录系统,我们需要知道用户名密码,spring security 默认的用户名是user,spring security启动的时候会生成默认密码(在启动日志中可以看到)。本例,我们指定一个用户名密码,在配置文件中加入如下内容:
默认的登陆用户是user
默认的登陆密码我们可以去控制台看下日志。会看到如下信息:
Using generated security password: b245fa16-9d7f-463b-bf41-7478713026c2
我们在登陆狂输入user
和密码 b245fa16-9d7f-463b-bf41-7478713026c2可以登录成功,并能访问/index/hello的内容。
1. 自定义security配置
上面我们看到默认情况下,Spring为我们提供了一个「httpBasic」模式的简单登陆页面,并在控制台输出了密码(这个密码每次启动都是不一样的)。如果我们想用自己的定义的账号密码,则需要改配置。如下
application.yml
spring:
# Spring Security 配置项,对应 SecurityProperties 配置类
security:
# 配置默认的 InMemoryUserDetailsManager 的用户账号与密码。
user:
name: user # 账号
password: user # 密码
roles: ADMIN # 拥有角色
启动项目从新登入
用户名 : user
密码 : user
项目地址
security-example-01 这个模块
https://gitee.com/gaibianzlp/spring-security-demo.git
参考文档