SpringSecurityOAuth2认证
SpringSecurityOAuth2认证
文章目录
- SpringSecurityOAuth2认证
- 一、OAuth2 协议四种授权方式
- 1.1、OAuth2 简单介绍
- 认证流程
- OAuth2五大角色
- 1.1、授权方式
- 1.2、授权码模式流程
- 1.3、密码模式流程
- 1.4、客户端模式流程
- 二、授权码认证
- 2.1、创建认证服务器
- 2.2、创建安全配置类
- 2.3、令牌访问端点
- 2.4、获取授权码
- 2.5、根据授权码获取token
- 三、密码授权模式(password)
- 3.1、配置密码模式
- 3.2、获取token
- 四、简化和客服端授权模式
- 4.1、简化模式
- 配置客户端授权类型
- 获取`token`
- 4.2、客户端模式
- 配置客服端授权类型
- 获取token
源码地址: https://github.com/gl-stars/springSecurity-example.git
一、OAuth2 协议四种授权方式
1.1、OAuth2 简单介绍
官网:https://oauth.net/2/
中文说明文档:https://github.com/jeansfish/RFC6749.zh-cn/blob/master/SUMMARY.md
OAuth 2.0 是目前最流行的授权机制,第三方应用授权登录:在APP或者网页接入一些第三方应用时,时常会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录,第三方应用通过oauth2方式获取用户信息。OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的规范标准。很多大公司如 阿里、腾讯、 Google,Yahoo,Microsoft等都提供了 OAuth 认证服务。
OAuth 协议1.0版本过于复杂,目前发展到2.0版本,2.0版本已得到广泛应用。
认证流程
OAuth
的思路是在”客户端”与”服务提供商”之间,设置了一个授权层(authorization layer)
。”客户端”不能直接登录”服务提供商”,只能登录授权层,以此将用户与客户端区分开来。”客户端”登录授权层所用的令牌(token
),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。”客户端”登录授权层以后,”服务提供商”根据令牌的权限范围和有效期,向”客户端”开放用户储存的资料。
OAuth2五大角色
- 资源所有者(Resource Owner)
通常为 “用户”(user),如昵称、头像等这些资源的拥有者(用户只是将这些资源放到了服务提供商的资源服务器中)。
- 第三方应用(Third-party application)
又称为客户端(Client),比如 梦学谷官网想要使用微信的资源(昵称、头像等),梦学谷官网对于QQ、微信等系统来说是第三者,我们称梦学谷官网为第三方应用。
- 认证服务器(Authorization server)
专门用来对资源所有者的身份进行认证、对要访问的资源进行授权、产生令牌的服务器。想访问资源,需要通过认证服务器由资源所有者授权后才可访问。
- 资源服务器(Resource server)
存储用户的资源(昵称、头像等)、验证令牌有效性。比如: 微信的资源服务器存储了微信的用户信息,淘宝的资源服务器存储了淘宝的用户信息等。注意:认证服务器 和资源服务器 虽然是两个解决,但其实他们可以是同一台服务器、同一个应用。
- 服务提供商(Service Provider)
如 QQ、微信等 (包含认证和资源服务器)。
绘图工具:https://c.runoob.com/more/shapefly-diagram/#
1.1、授权方式
- 授权码模式
(Authorization Code)
功能最完整,流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。国内各大服务提供商(微信、QQ
、微博、淘宝 、百度)都采用此模式进行授权。可以确定是用真正同意授权;而且令牌是认证服务器发放给第三方应用的服务器,而不是浏览器上。
- 简化模式(
Implicit
)
令牌是发放给浏览器的,oauth客户端运行在浏览器中 ,通过JS脚本去申请令牌。而不是发放给第三方应用的服务器。
- 密码模式
(Resource Owner Password Credentials)
将用户名和密码传过去,直接获取 access_token
。用户同意授权动作是在第三方应用上完成 ,而不是在认证服务器上。第三方应用申请令牌时,直接带着用户名密码去向认证服务器申请令牌。这种方式认证服务器无法断定用户是否真的授权了,用户名密码可能是第三方用盗取来的。
- 客户端证书模式
(Client credentials)
使用比较少,当一个第三应用自己本身需要获取资源(而不是以用户的名
义),而不是获取用户的资源时,客户端模式十分有用。
1.2、授权码模式流程
具体步骤如下:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
1.3、密码模式流程
- 用户向客户端直接提供认证服务器平台的用户名和密码。
- 客户端将用户名和密码发给认证服务器,向后者请求令牌。
- 认证服务器确认无误后,向客户端提供访问令牌。
1.4、客户端模式流程
- 客户端向认证服务器进行身份认证,并要求一个访问令牌。
- 认证服务器确认无误后,向客户端提供访问令牌。
客户端模式(Client Credentials Grant)
指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
它的步骤如下:
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
客户端发出的HTTP
请求,包含以下参数:
granttype
:表示授权类型,此处的值固定为"clientcredentials
",必选项。
scope
:表示权限范围,可选项。
二、授权码认证
2.1、创建认证服务器
配置方式说明
- 内存方式
- 数据库管理方式
令牌管理
- 令牌管理策略(
JDBC
、Redis
、JWT
) - 令牌生成策略
- 令牌端点
- 令牌端点的安全配置
- 令牌管理策略(
配置认证服务器(授权码模式)
配置允许访问该认证服务器的客户端资源,没有在这里配置的客户端是不能访问的。如果在这里配置后,访问是必须带上这里配置的客户端名称和密码。
- 创建认证服务器配置类
AuthorizationServerConfig
创建 AuthorizationServerConfig
类并继承 AuthorizationServerConfigurerAdapter
类,实现 public void configure(ClientDetailsServiceConfigurer clients)
方法。在类上添加 @Configuration
注解标识是配置类,@EnableAuthorizationServer
注解开启OAuth2
认证服务器功能。
- 内存方式配置说明
withClient
(必须):允许访问此认证服务器的客户端id , 如:PC、APP、小程序各不同的的客户端id。
secret
(必须):客户端密码,要加密存储,不然获取不到令牌一直要求登录, 而且一定不能被泄露。
resourceIds
(非必须):资源服务器id,就相当于微服务id,可以使用逗号隔开,配置多个。如果不配置,所有的资源服务器(每个微服务)都可以访问。
authorizedGrantTypes
: 授权类型, 可同时支持多种授权类型:
可配置:“authorization_code”, “password”, “implicit”,“client_credentials”,“refresh_token”。这些值是固定的,可以配置多个。
authorization_code:授权码
password:密码模式
implicit:简化模式
client_credentials:客户端模式
refresh_token:刷新令牌
scopes
(非必须):授权范围标识,如指定微服务名称,则只能访问指定的微服务。
autoApprove
(非必须):false 跳转到授权页面手动点击授权,true 不用手动授权,直接响应授权码。
redirectUris
(非必须) 当获取授权码后,认证服务器回调地址,并且带着一个授权码 code
响应回来。
2.2、创建安全配置类
创建安全配置类 SpringSecurityConfig
并继承 WebSecurityConfigurerAdapter
类,实现 configure(AuthenticationManagerBuilder auth)
方法。在该类上添加 @EnableWebSecurity
注解,开启SpringSecurity
过滤连file
,但是这个注解已经包含 @Configuration
注解了,所以这个类上就不用再添加这个注解。
2.3、令牌访问端点
Spring Security
对OAuth2
默认提供了可直接访问端点,就是在访问的URL
地址。
/oauth/authorize
:申请授权码code
, 涉及的类AuthorizationEndpoint
/oauth/token
:获取令牌token
, 涉及的类TokenEndpoint
/oauth/check_token
:用于资源服务器请求端点来检查令牌是否有效, 涉及的类CheckTokenEndpoint
/oauth/confirm_access
:用户确认授权提交, 涉及的类WhitelabelApprovalEndpoint
/oauth/error
:授权服务错误信息, 涉及的类WhitelabelErrorEndpoint
/oauth/token_key
:提供公有密匙的端点,使用 JWT 令牌时会使用 , 涉及的类TokenKeyEndpoint
2.4、获取授权码
直接访问令牌对应的访问端点/oauth/authorize
,根据用户名和密码登录成功后就可以获取到授权码。
注意本地的端口为8090
,服务器名称为auth
,所以访问的时候需要在最前面添加上这个服务器名称才能访问到。访问地址为:
http://localhost:8090/auth/oauth/authorize?client_id=sse-pc&response_type=code
提交方式:
post
client_id
客户端id
response_type
:相应的类型是code
授权码
当在浏览器访问这个地址时,自动跳转到登录页面,输入安全配置类 SpringSecurityConfig
中配置的用户名和密码。点击登录后,如果配置的是自动授权,会自动跳转到我们配置的客户端回调地址,路径最后带有code
参数,这个参数值就是授权码了,如果不是自动授权,那么会弹出一个授权页面授权才能获取授权码。
2.5、根据授权码获取token
打开postman
,使用post
提交方式,访问地址为:http://localhost:8090/auth/oauth/token。这个访问地址是令牌访问端点配置好了,auth
是服务器的名称,在yml
文件中配置的,上面也说明了。
配置将“客户端id”和“客户端密码”加密了,加密步骤如下。
点击发送后,会返回令牌的相关信息,返回结果如下。
{"access_token": "4be57993-2eb2-420a-bdc3-ec108601324d","token_type": "bearer","refresh_token": "4e84f086-b916-4c0f-83c0-8ee6eb36cb24","expires_in": 43199,"scope": "all"
}
access_token
:令牌
token_type
:令牌类型,返回都是这个值
refresh_token
:刷新令牌
expires_in
:令牌的时差,一般是12个小时
scope
:访问范围,在.scopes("all")
这里配置的。
每一个授权码只能申请一次令牌,不管申请失败还是成功,都只能申请一次。但是同一个用户不同的授权码获取到的令牌都是一样的。
出现这样的局面,说明授权码回娘家休息去了,你要重新发送 http://localhost:8090/auth/oauth/authorize?client_id=sse-pc&response_type=code
这个地址重新获取授权码,不要一直在重定向回来的那个地址一直刷新,结果发现授权码一直都是那样,因为你并没有重新获取授权码,这是一种很愚蠢的做法。
当前版本号:e8656486abd96ec334eb373389ef0d029d47218a
三、密码授权模式(password)
密码模式(Resource Owner Password Credentials Grant
)中 ,用户向客户端提供自己在服务提供商(认证服务器)上的用户名和密码,然后客户端通过用户提供的用户名和密码向服务提供商(认证服务器)获取令牌。如果用户名和密码遗漏,服务提供商(认证服务器)无法判断客户端提交的用户和密码是否盗取来的,那意味着令牌就可随时获取,数据被丢失。适用于产品都是企业内部的,用户名密码共享不要紧。如果是第三方这种不太适合,也适用手机APP提交用户名密码。
3.1、配置密码模式
在安全配置类 SpringSecurityConfig
重写 authenticationManagerBean()
方法,将 AuthenticationManager
到容器中。
在认证服务器中AuthorizationServerConfig
覆写 configure(AuthorizationServerEndpointsConfigurer endpoints)
方法,将AuthenticationManager
认证管理器注入。
授权类型就不用管了,这里已经设置好了,可以使用密码模式的。
// 授权类型, 可同时支持多种授权类型.authorizedGrantTypes("authorization_code", "password","implicit","client_credentials","refresh_token")
3.2、获取token
获取的令牌端点也是一样的,都是/oauth/token
。访问地址如下:
http://localhost:8090/auth/oauth/token
注意要将grant_type更改为password
当前版本号:7583d883ffd76f0cc95797498c854f0a1538f0f7
四、简化和客服端授权模式
4.1、简化模式
不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌 ,不需要先获取授权码。直接可以一次请求就可得到令牌,在 redirect_uri
指定的回调地址中传递令牌( access_token
)。该模式适合直接运行在浏览器上的应用,不用后端支持(例如 Javascript
应用) 。
注意:只要客户端id即可 ,客户端密码都不需要。
配置客户端授权类型
实现简化模式需要在认证服务器 AuthorizationServerConfig
的authorizedGrantTypes
中配置授权类型为implicit
,简化模式才可以生效。
获取token
获取token
的令牌端点/oauth/authorize
,访问地址如下:
http://localhost:8090/auth/oauth/authorize?client_id=sse-pc&response_type=token
auth
:服务器名称,在yml中自己配置的
client_id
:客服端id
response_type
:相应类型是token
访问这个地址后,会跳转到登录页面进行登录。登录成功跳转到重定向的URL
地址,后面就带上token了。
https://www.baidu.com/
#access_token=92d70c3f-2172-4a9e-9ba0-39428659e057
&token_type=bearer
&expires_in=43199
&scope=all
access_token
:令牌
token_type
:令牌类型,返回都是这个值
expires_in
:令牌的时差,一般是12个小时
scope
:访问范围,在.scopes("all")
这里配置的。
4.2、客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向服务提供商(认证服务器)进行认证。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求服务提供商(认证服务器)提供服务,其实不存在授权问题。客户端向认证服务器进行身份认证,并要求一个访问令牌。认证服务器确认无误后,向客户端提供访问令牌。
配置客服端授权类型
在认证服务器中AuthorizationServerConfig
通过authorizedGrantTypes
指定客服端模式。
获取token
既然是以客服端为名义,而不是用户的名义去获取令牌。那么用户登录这个步骤就没有了,并且这个模式是没有刷新令牌的。使用的令牌端点/oauth/token
,访问地址如下:
http://localhost:8090/auth/oauth/token
当前版本号:eeda16403ee90bf8fd76883cd189d66aa500b02f
SpringSecurityOAuth2认证相关推荐
- 正在向icntv服务器认证授权信息,Spring-Security-OAuth2服务器之搭建认证授权服务器[一]...
结构基础 基础框架:Spring Boot + Spring-Security-OAuth2 存储介质:Mysql + Redis 持久化方式:Spring-data-jpa 测试工具:Postman ...
- 分布式系统认证解决方案SpringSecurityOAuth2.0(二)分布式系统认证流程分析与实现
目录 文章 一.简介 1.1 OAuth2.0协议角色 1.2 SpringSecurityOAuth2.0 二.认证流程 三.授权服务器--代码实现 3.1 主要依赖 3.2 Authorizati ...
- Spring Boot 2.0 利用 Spring Security 实现简单的OAuth2.0认证方式1
0. 前言 之前帐号认证用过自己写的进行匹配,现在要学会使用标准了.准备了解和使用这个OAuth2.0协议. 1. 配置 1.1 配置pom.xml 有些可能会用不到,我把我项目中用到的所有包都贴出来 ...
- spring-security-oauth2注解详解
spring-security-oauth2支持的注解有: 1.EnableOAuth2Client 适用于使用spring security,并且想从Oauth2认证服务器来获取授权的web应用环境 ...
- 认证服务器的搭建_OAuth2.0分布式系统环境搭建
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:http://github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 介绍 OAuth( ...
- spring-security-oauth2实现OAuth2.0服务
关于OAuth的介绍查看我的另一篇文章OAuth的4种授权方式,spring-security-oauth2是实现OAuth2.0的框架,配置稍微有些繁琐,因此本文记录下大概的思路,加深印象. OAu ...
- spring-security认证授权
授权是在认证后对资源的权限控制,权限控制很多系统中都需要,但是不同的系统对于权限的敏感程度不同,因而权限的设计实现方式不同. rbac权限模型可以分为基于角色的权限控制和基于资源的权限控制 基于角色的 ...
- 基础平台为第三方应用接入提供oauth2认证接口
oauth2开放认证协议原理及案例分析 http://blog.csdn.net/volcan1987/article/details/7287605 谈谈基于OAuth 2.0的第三方认证 [上篇] ...
- SpringCloud+OAuth2+Redis实现的微服务统一认证授权
作者:myCat blog.csdn.net/WYA1993/article/details/85050120 开发环境: Windows10 Intellij Idea2018.2 jdk1.8 r ...
最新文章
- Spring集成Redis方案(spring-data-redis)(基于Jedis的单机模式)(待实践)
- maven 创建module失败 ,异常Unable to read parent POM
- Servlet线程安全2
- WIN2003 X64 系统上安装sql server 2000 的步骤
- Mac下IDEA安装Protobuf插件
- SpringBoot基础篇日志管理之logback配置文件
- python可以操作word吗_python实现在windows下操作word的方法
- index.php文件分析,OpenCart index.php分析
- mysql基础2-数据库的相关操作
- lsqcurvefit拟合结果为复数_高考数学专题突破,向量运算与复数运算、算法、推理与证明,方法规律总结,知识归纳,易错示警...
- 通信产业2017走向后摩尔时代
- vmstat记录linux状态日志到文本-随手记
- 一篇文章教会你使用Python定时抓取微博评论
- 个人收藏的一些实用网站整理
- meanshift算法通俗讲解
- 【Unity】Unity寻路系统讲解及Navigation实际应用
- Hex Fiend – 十六进制编辑 [Mac]
- search函数和search_n()函数
- 论文阅读笔记:A Network-based End-to-End Trainable Task-oriented Dialogue System
- No view found for id 0x7f05003c (*) for fragment PlaceholderFragment