行业知识
Spring Security OAuth2详解
1、简介
spring security oauth2框架即spring security + OAuth2,spring security上一篇文章已经讲过,接下来讲讲OAuth2,它是行业标准的授权协议,旨在为开发人员提供简单易用的授权流程;OAuth 定义了四种角色:
- 资源所有者:能够授予对受保护资源的访问权限的实体,当资源所有者是一个人时,它被称为最终用户。
- 资源服务器:托管受保护资源的服务器,能够接受并使用访问令牌响应受保护的资源请求。
- 授权服务器:服务器成功后向客户端颁发访问令牌验证资源所有者并获得授权。
- 客户:一个应用程序代表资源所有者及其授权。“客户”一词确实不暗示任何特定的实现特征(例如,应用程序是在服务器、桌面还是其他平台上执行 设备)。
2、OAuth2授权模式
2.1 授权码模式
OAuth2有四种授权模式,其中授权码模式作为最常见的授权模式,在web端与app端都得到广泛的使用,比如微信账号授权登录京东、知乎等;
授权码模式与其他三种授权模式不同,其流程从客户端启动浏览器开始,具体步骤如下
- 客户端打开浏览器将用户信息发送到OAuth2认证服务器
- 用户看到授权提示并批准客户端的请求
- 认证服务器将页面重定向至redirect_uri,并在url中拼接授权码code
- 客户端通过code交换访问令牌token
刷新token流程
2.2 密码模式
密码模式作为最不安全的授权模式,它通过给定的用户名密码获取访问令牌token,已在最新的oauth2最佳安全当前实践OAuth 2.0 Security Best Current Practice中被禁止;OAuth2对密码模式的支持,是为了让OAuth之前的系统无需任何用户交互即可升级至OAuth;之前的认证方式是HTTP Basic Auth,浏览器会存储用户密码并在每次请求服务端时将其带上,这种方式存在很多局限性和安全隐患;密码模式允许用户继续在浏览器端通过用户名密码交换访问令牌,以便将来使用访问令牌无缝升级到 OAuth
2.3 客户端模式
客户端模式也叫客户端凭证模式,其旨在解决内部服务之间相互调用的鉴权问题;资源服务器A从认证服务器中获取token,携带token访问资源服务器B,资源服务器B请求认证服务器校验token;这种交互方式导致内部服务之间的每一次调用都需要向认证服务器发送一次请求,这极大地增加了客户端的响应时间。这种业务场景强烈推荐使用JSON Web Tokens(JWT),它无状态且支持本地验证;JWT 包含三个部分:标头、有效负载和签名。标头和有效负载是简单的 base64 编码字符串,可以轻松解密和读取。签名使用标头中列出的算法以及私钥来创建标头和有效负载的哈希值。没有私钥无法重新创建散列,但可以使用公钥对其进行验证;现代计算机需要数年时间才能暴力破解有效的 JWT 签名,但JWT有效期默认是一小时
2.4 隐式模式
隐式模式也叫简单模式,是一种简化的OAuth流程,起初推荐用于本机或者JavaScript应用程序,访问令牌立即返回,无需额外的授权步骤;强烈不建议使用该授权模式,因为在 HTTP 重定向中返回访问令牌存在极大风险;隐式模式与授权码模式流程类似,认证服务器重定向回客户端页面拼接在URL上的不再是授权码code,而是访问令牌token;具体步骤如下
- 客户端打开浏览器将用户名密码发送到OAuth认证服务器
- 用户看到授权提示并批准客户端的请求
- 认证服务器将页面重定向至redirect_uri,并在url中拼接授权码token
3、快速开始
3.1 创建工程
创建springboot工程并添加相关依赖,此处注意Spring-boot-starter-parent版本号
4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE com.fsk hello-security-oauth2-server 0.0.1-SNAPSHOT hello-security-oauth2-server hello-security-oauth2-server 1.8 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter org.springframework.cloud spring-cloud-starter-oauth2 org.springframework.cloud spring-cloud-starter-security org.projectlombok lombok org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin 创建认证服务器配置类AuthorizationServerConfig,继承WebSecurityConfigurerAdapter;并添加开启认证服务器注解@EnableAuthorizationServer
@EnableAuthorizationServer@Configurationpublic class AuthorizationServerConfig extends WebSecurityConfigurerAdapter{} 此时启动服务控制台中打印password、client-id和client-secret信息
Using generated security password: 3317924e-7d73-4482-aa1d-307e6af50b18 security.oauth2.client.client-id = e5de4306-b216-408a-829e-9e57414a3c02 security.oauth2.client.client-secret = f341b207-5d33-4892-96b9-753ae7cc2219
在配置文件application.yml中添加如下配置指定client-id和client-secret
security: oauth2: client: client-id: fsk client-secret: fsk123
再次启动服务,控制台打印信息如下
security.oauth2.client.client-id = fsksecurity.oauth2.client.client-secret = ****
创建配置类SecurityConfig、用户信息接口UserDetailService和用户实体类MyUser