`
m635674608
  • 浏览: 5029418 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

使用JWT的OAuth2的SSO分析

 
阅读更多

参考:https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/oauth2/README.adoc
http://jwt.io/introduction/
本文在<使用OAuth2的SSO分析>文章的基础上扩展,使用jwt可减少了向认证服务器的请求,但jwt比swt(Simple Web Tokens)要长不少,还要依赖公钥解密.
这里写图片描述
1.浏览器向UI服务器点击触发要求安全认证
2.跳转到授权服务器获取授权许可码
3.从授权服务器带授权许可码跳回来
4.UI服务器向授权服务器获取AccessToken
5.返回AccessToken到UI服务器
6.发出/resource/请求到UI服务器
7.UI服务器将/resource/请求转发到Resource服务器
Resource服务器从请求取出accessToken,解码,直接转化为认证授权信息进行判断后(最后会响应给UI服务器,UI服务器再响应给浏览中器)

这里与<使用OAuth2的SSO分析>主要不同的是,accessToken是jwt,经过解码,转化就可成为认证授权信息,无需再 向授权服务器协助获得认证授权信息,关于jwt可参看前面提供的链接.本文还修改了自定义登录页和授权页,这种方案开始接近于生产了.

一.先创建OAuth2授权服务器
1.因为使用了自定义页面,添加了wro4j-maven-plugin插件和以下依赖到pom.xml

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.主类修改比较大,主类继承WebMvcConfigurerAdapter主要是注册视图控制器;继承 WebSecurityConfigurerAdapter的内部类主要修改自定义权限控制;关键是继承 AuthorizationServerConfigurerAdapter的授权服务器配置,里面配置了 JwtAccessTokenConverter(密钥就在这里使用),并使用这个Bean;@EnableResourceServer一样是放在主类 上.
3.application配置将oauth的配置移到了OAuth2AuthorizationConfig内部类内部.增加了一个密钥库文件和两个freemarker页面
启动授权服务器后,可测试了:
a.打开浏览器输入地址http://localhost:9999/uaa/oauth/authorize?response_type=code&client_id=acme&redirect_uri=http://example.com发出请求,然后根据以上配置,输入用户名/密码,点同意,获取返回的授权许可码
b.在linux的bash或mac的terminal输入
[root@dev ~]#curl acme:acmesecret@192.168.1.115:9999/uaa/oauth/token \
-d grant_type=authorization_code -d client_id=acme \
-d redirect_uri=http://example.com -d code=fjRdsL
回车获取access token,其中fjRdsL替换上步获取的授权许可码.返回结果类似如下:
{"access_token":"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0NTk1NTUxNTYsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIiwiUk9MRV9VU0VSIl0sImp0aSI6IjI5MjcyYWJiLTQ4MjUtNGYwMS1hZjllLTg5ZGE1ZDE1MDBiNyIsImNsaWVudF9pZCI6ImFjbWUiLCJzY29wZSI6WyJvcGVuaWQiXX0.cQd88GYItHUDJuwkd_Rd0Yo8QM1R0dccuK0-xZ4OynC7EnqClLunaNOZ9jXwtilIFJNxbkbhQ8ymXdvlAF5Zjo8lpRGotdVo9rgQc39BDse7hGy1EfA9ZADQmJ-EuwkTNo0IBEXYC33XxQNK_3I_E92cnIPXq-FZHuZMRzpr-SlriwLa3aZVidmeyXK2U5dsjViWoHHKhcg-9c-VBPtyTJfPZOvj3s7DrbfCgOAGOhHkd_MBCdLDFb7QFhzIRsMfcD9rOAGTqk-hU2pHkkakKQ7_vL604UU7Qh3Zzkn6VbHPy0HAAiB9cnUhkQxK3Qb-wbHG-l3FC2pDlhtlhMHNfg","token_type":"bearer","refresh_token":"eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ1c2VyIiwic2NvcGUiOlsib3BlbmlkIl0sImF0aSI6IjI5MjcyYWJiLTQ4MjUtNGYwMS1hZjllLTg5ZGE1ZDE1MDBiNyIsImV4cCI6MTQ2MjEwMzk1NiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiJdLCJqdGkiOiIzNWM5OWY0Yy0xMGM0LTQ5ZTAtODAwYi1lZTc5ZTQ3ODNkNmUiLCJjbGllbnRfaWQiOiJhY21lIn0.bUvJ9HmrFU92euLzd5eesJKFlav5v1WyfBEgd3pO6I2D2yYy98oPwfNwCrbP44M2ilO48LJEovLLoZFYvjfA8xe6XO1Fx55Tik5SrWfizAEsNFsFg25zE92T3YNocStxuJWFSVBLlwjtxpVmnHOgPefku2G6N5seziX0SOBJleHSUObNAYtiBVQjKWXA3jGnMoZSP0dMbgtrWinwRJLwvaMgMDNnxYFSdvSW99XKjCyQNVmbGa4aRyy-xblTr7qlSqdcZIdRBfKkHM5S9jaenNVc85vGAYQFPrdkRWhk4v-8nlHJiYdBa6ZspgbVWw_oPLgP8cbuzJev86q55p1gAw","expires_in":43199,"scope":"openid","jti":"29272abb-4825-4f01-af9e-89da5d1500b7"}
从返回结果复制access_token,继续:
[root@dev ~]# TOKEN=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0NTk1NTUxNTYsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIiwiUk9MRV9VU0VSSI6IjI5MjcyYWJiLTQ4MjUtNGYwMS1hZjllLTg5ZGE1ZDE1MDBiNyIsImNsaWVudF9pZCI6ImFjbWUiLCJzY29wZSI6WyJvcGVuaWQiXX0.cQd88GYItHUDJuwkd_Rd0Yo8QM1R0dccuK0-xZ4OynC7EnqClLunaNOZ9jXwtilIFJNxbkbhQ8ymXdvlAF5Zjo8lpRGotdVo9rgQc39BDse7hGy1EfA9ZADQmJ-EuwkTNo0IBEXYC33XxQNK_3I_E92cnIPXq-FZHuZMRzpr-SlriwLa3aZVidmeyXK2U5dsjViWoHHKhcg-9c-VBPtyTJfPZOvj3s7DrbfCgOAGOhHkd_MBCdLDFb7QFhzIRsMfcD9rOAGTqk-hU2pHkkakKQ7_vL604UU7Qh3Zzkn6VbHPy0HAAiB9cnUhkQxK3Qb-wbHG-l3FC2pDlhtlhMHNfg
[root@dev ~]# curl -H “Authorization: Bearer $TOKEN” 192.168.1.115:9999/uaa/user
第二个命令返回结果类似如下:
{"details":{"remoteAddress":"192.168.1.194","sessionId":null,"tokenValue":"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0NTk1NTUxNTYsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIiwiUk9MRV9VU0VSIl0sImp0aSI6IjI5MjcyYWJiLTQ4MjUtNGYwMS1hZjllLTg5ZGE1ZDE1MDBiNyIsImNsaWVudF9pZCI6ImFjbWUiLCJzY29wZSI6WyJvcGVuaWQiXX0.cQd88GYItHUDJuwkd_Rd0Yo8QM1R0dccuK0-xZ4OynC7EnqClLunaNOZ9jXwtilIFJNxbkbhQ8ymXdvlAF5Zjo8lpRGotdVo9rgQc39BDse7hGy1EfA9ZADQmJ-EuwkTNo0IBEXYC33XxQNK_3I_E92cnIPXq-FZHuZMRzpr-SlriwLa3aZVidmeyXK2U5dsjViWoHHKhcg-9c-VBPtyTJfPZOvj3s7DrbfCgOAGOhHkd_MBCdLDFb7QFhzIRsMfcD9rOAGTqk-hU2pHkkakKQ7_vL604UU7Qh3Zzkn6VbHPy0HAAiB9cnUhkQxK3Qb-wbHG-l3FC2pDlhtlhMHNfg","tokenType":"Bearer","decodedDetails":null},"authorities":[{"authority":"ROLE_ADMIN"},{"authority":"ROLE_USER"}],"authenticated":true,"userAuthentication":{"details":null,"authorities":[{"authority":"ROLE_ADMIN"},{"authority":"ROLE_USER"}],"authenticated":true,"principal":"user","credentials":"N/A","name":"user"},"credentials":"","principal":"user","oauth2Request":{"clientId":"acme","scope":["openid"],"requestParameters":{"client_id":"acme"},"resourceIds":[],"authorities":[],"approved":true,"refresh":false,"redirectUri":null,"responseTypes":[],"extensions":{},"grantType":null,"refreshTokenRequest":null},"clientOnly":false,"name":"user"}
从结果来看,使用access token访问资源一切正常,说明授权服务器没问题.

二.再看分离的资源服务器
spring-security-jwt依赖也要加入pom.xml;主类没改动;application配置文件使用 security.oauth2.resource.jwt.keyValue替换 security.oauth2.resource.userInfoUri选项,使用这个公钥来解密jwt.

最后运行主类的main方法测试(授权服务器前面启动了,access_token也得到了),于是在使用curl命令:
[root@dev ~]# curl -H “Authorization: Bearer $TOKEN” 192.168.1.115:9000
返回结果类似如下:
{"id":"03af8be3-2fc3-4d75-acf7-c484d9cf32b1","content":"Hello World"}
跟踪下获取认证授权的信息过程:
当使用curl -H “Authorization: Bearer $TOKEN” 192.168.1.115:9000发出请求时,直到被OAuth2AuthenticationProcessingFilter拦截器处理,
org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter#doFilter{
Authentication authentication = tokenExtractor.extract(request);//抽取Token
Authentication authResult = authenticationManager.authenticate(authentication);//还原解码认证授权信息
}
org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager#authenticate{
OAuth2Authentication auth = tokenServices.loadAuthentication(token);//这里的tokenServices是DefaultTokenServices
}
org.springframework.security.oauth2.provider.token.DefaultTokenServices#loadAuthentication{
OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue);//tokenStore是JwtTokenStore
OAuth2Authentication result = tokenStore.readAuthentication(accessToken);
}
org.springframework.security.oauth2.provider.token.store.JwtTokenStore#readAccessToken{
OAuth2AccessToken accessToken = convertAccessToken(tokenValue);
}
org.springframework.security.oauth2.provider.token.store.JwtTokenStore#convertAccessToken{
return jwtTokenEnhancer.extractAccessToken(tokenValue, jwtTokenEnhancer.decode(tokenValue));
}
org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter#extractAccessToken
经过上面这个过程,用到jwt的公钥对jwt进行解码,,从中抽取OAuth2Authentication,这个Authentication本身就包含了用户认证的信息.无需再向授权服务器发请求解码

三.UI服务器作为SSO的客户端.
同样UI服务器也要添加spring-security-jwt依赖到pom.xml;主类也基本不改动;和资源服务器一样,使用 security.oauth2.resource.jwt.keyValue替换 security.oauth2.resource.userInfoUri选项.其它的分析与<使用OAuth2的SSO分析>类似.可以 三台服务器都启动测试了.

 

http://m.fx114.net/qa-235-319551.aspx

分享到:
评论

相关推荐

    spring security oauth2以及jwt实现sso单点登陆的功能

    综上所述,本项目利用Spring Security OAuth2提供的授权框架和JWT的安全特性,构建了一个能够跨应用实现SSO的解决方案。用户只需在首次登录时进行验证,之后在所有支持SSO的应用中都可以无缝切换,提升了用户体验。

    spring security oauth2 实现jwt sso

    Spring Security OAuth2 与 JWT 实现的SSO详解 在当今的互联网应用中,单点登录(Single Sign-On,简称SSO)已经成为一种常见的身份验证机制,它允许用户在一个系统中登录后,无需再次登录就能访问其他关联系统。在...

    基于JWT OAUTH2 SpringSecurity单点登录

    基于JWT OAUTH2 SpringSecurity单点登录 . 单点登录流: 1. 访问client1 2. `client1`将请求导向`sso-server` 3. 同意授权 4. 携带授权码`code`返回`client1` 5. `client1`拿着授权码请求令牌 6. 返回`JWT`令牌 7. ...

    Spring Cloud 集成OAuth2实现身份认证和单点登录

    通过分析和运行这些示例,开发者可以更好地理解和掌握Spring Cloud环境下的OAuth2和SSO集成。 为了成功地实现这一集成,开发者还需要理解以下关键概念: - 授权类型:如授权码流程、隐式流程、密码流程和客户端...

    基于JWT实现SSO单点登录流程图解

    认证服务需要在pom.xml文件中添加相关依赖,例如spring-security-oauth2-autoconfigure和spring-security-jwt。 2. 应用服务器(应用A和应用B) 应用服务器是用户访问的入口,负责处理用户请求。它们使用JWT来验证...

    spring security 基于oauth 2.0 实现 sso 单点登录Demo.zip

    spring security 基于oauth 2.0 实现 sso 单点登录Demo 使用 spring security 基于oauth 2.0 实现 sso 单点登录Demo spring boot + spring security + spring security oauth

    基于Spring Cloud、OAuth2.0、Vue的前后端分离的系统

    系统可能集成了CAS、OAuth2.0或JWT等技术来实现多系统间的SSO,提升用户体验。 10. **Vue.js**: Vue.js 是一个轻量级的前端JavaScript框架,用于构建用户界面。Vue的特点包括声明式渲染、组件化、虚拟DOM和响应式...

    模拟OAuth2 单点登录

    理解并实现OAuth2和SSO的Java代码涉及到大量的配置和编码工作,包括Spring Security的配置、OAuth2的流程控制、JWT的生成和验证等。在实际开发中,需要对这些概念有深入的理解,才能确保系统的安全性和可靠性。通过...

    springboot shiro pac4j cas jwt认证中心sso完整项目

    6. **子应用接入**:子应用配置为使用Shiro进行鉴权,检查JWT来决定是否允许访问。 这个项目不仅展示了SSO的实现,还涵盖了现代Web应用中的许多安全和架构设计实践,对于学习和理解分布式系统中的身份验证和授权...

    springboot整合Oauth2,GateWay实现网关登录授权验证

    在实际操作中,我们可能还需要考虑一些高级特性,例如刷新令牌、令牌过期策略、单点登录(SSO)以及JWT(JSON Web Tokens)的使用。JWT可以减少与授权服务器的交互次数,提高系统性能。在Spring Boot中,可以使用...

    Oauth2-SSO:使用Oauth2实现的SSO单点登录登出,模拟微信QQ授权码模式授权资源访问

    将JWT方式的令牌改成Oauth2系统自己实现的令牌方式,同时将令牌存入Redis,同时将oauth_client_details数据库存储加入Redis缓存。 demo使用时,添加DNS域名解析(Windows):C:\ Windows \ System32 \ drivers \ ...

    通俗易懂版讲解JWT和OAuth2,以及他俩的区别和联系.docx

    两者之间的联系在于,JWT可以作为OAuth2的一部分使用,即OAuth2可以采用JWT作为访问令牌。在这种情况下,OAuth2定义了如何获取JWT,而JWT定义了令牌的内容结构和验证机制。 #### 结论 总的来说,OAuth2和JWT虽然都...

    基于oauth2+security实现的SSO单点登录案例

    本案例基于Spring Security OAuth2来实现SSO,这是一个强大的安全框架,结合OAuth2协议,为分布式系统提供了灵活的身份验证和授权解决方案。 首先,Spring Security是Spring生态系统中的一个安全组件,它提供了全面...

    12.OAuth2授权之基于JWT完成单点登录

    在这个例子中,我们将创建一个oauth2-client模块作为需要登录的客户端服务,并使用oauth2-jwt-server服务作为授权服务。 单点登录简介 单点登录(Single Sign On)指的是当有多个系统需要登录时,用户只需登录一个...

    SpringCloud+SpringBoot+OAuth2+Spring Security+Redis实现的微服务统一认证授权.doc

    SpringCloud+SpringBoot+OAuth2+Spring Security+Redis实现的微服务统一认证授权

    单点登录JWT、CAS、Oauth2、SAML几种技术方案对比分析

    本文将对比分析四种常见的SSO技术:JWT、CAS、OAuth2和SAML。 1. 基于JWT的单点登录: JWT(Json Web Token)是一种开放标准,用于在各方之间安全地传输信息。在SSO场景中,JWT作为用户身份验证的凭证,具有紧凑且...

    第九章 SpringCloud Oauth2认证中心-Zuul网关上添加认证.pdf

    3. 获取并使用OAuth2服务器的公钥进行JWT验证。 4. 在Zuul网关中配置OAuth2认证,包括引入相关依赖和更新配置。 5. 使用Zuul进行安全路由,确保只有经过有效认证的请求才能访问服务。 这些步骤帮助我们在微服务架构...

    SpringGateway集成Oauth2进行认证授权及SSO

    2. `AuthorizationServerConfig`:配置OAuth2的授权服务器,包括使用jdbc+jwt的方式设置令牌生成策略。 3. `SecurityConfig`:定义安全配置,如登录页面、授权页面的路径,以及授权规则。 4. `JdbcUserDetails`:...

    oauth2-sso-samples:扩展 Spring OAuth2 tonrsparklr 示例以支持单点登录

    oauth2-sso-samples 扩展 Spring OAuth2 ...使用“现有 Maven 项目”导入 tonr、sparklr、keyhole 和 oauth2sso 项目(导入 -&gt; Maven) 如有必要,还从 spring-security-oauth 导入“spring-security-oauth2”和

Global site tag (gtag.js) - Google Analytics