概 述

在前文《基于Spring Security和 JWT的权限系统设计》之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Spring Security Oauth2实现的多系统单点登录(SSO)和 JWT权限控制功能,毕竟这个需求也还是蛮普遍的。

代码已开源,放在文尾,需要自取

理论知识

在此之前需要学习和了解一些前置知识包括:

Spring Security:基于 Spring实现的 Web系统的认证和权限模块

OAuth2:一个关于授权(authorization)的开放网络标准

单点登录 (SSO):在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统

JWT:在网络应用间传递信息的一种基于 JSON的开放标准((RFC 7519),用于作为JSON对象在不同系统之间进行安全地信息传输。主要使用场景一般是用来在 身份提供者和服务提供者间传递被认证的用户身份信息

要完成的目标

目标1:设计并实现一个第三方授权中心服务(Server),用于完成用户登录,认证和权限处理

目标2:可以在授权中心下挂载任意多个客户端应用(Client)

目标3:当用户访问客户端应用的安全页面时,会重定向到授权中心进行身份验证,认证完成后方可访问客户端应用的服务,且多个客户端应用只需要登录一次即可(谓之 “单点登录 SSO”)

基于此目标驱动,本文设计三个独立服务,分别是:

一个授权服务中心(codesheep-server)

客户端应用1(codesheep-client1)

客户端应用2(codesheep-client2)

多模块(Multi-Module)项目搭建

三个应用通过一个多模块的 Maven项目进行组织,其中项目父 pom中需要加入相关依赖如下:

org.springframework.boot

spring-boot-dependencies

2.0.8.RELEASE

pom

import

io.spring.platform

platform-bom

Cairo-RELEASE

pom

import

org.springframework.cloud

spring-cloud-dependencies

Finchley.SR2

pom

import

项目结构如下:

授权认证中心搭建

授权认证中心本质就是一个 Spring Boot应用,因此需要完成几个大步骤:

pom中添加依赖

org.springframework.cloud

spring-cloud-starter-oauth2

项目 yml配置文件:

server:

port: 8085

servlet:

context-path: /uac

即让授权中心服务启动在本地的 8085端口之上

创建一个带指定权限的模拟用户

@Component

public class SheepUserDetailsService implements UserDetailsService {

@Autowired

private PasswordEncoder passwordEncoder;

@Override

public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

if( !"codesheep".equals(s) )

throw new UsernameNotFoundException("用户" + s + "不存在" );

return new User( s, passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_NORMAL,ROLE_MEDIUM"));

}

}

这里创建了一个用户名为codesheep,密码 123456的模拟用户,并且赋予了 普通权限(ROLE_NORMAL)和 中等权限(ROLE_MEDIUM)

认证服务器配置 AuthorizationServerConfig

这里做的最重要的两件事:一是 定义了两个客户端应用的通行证(sheep1和sheep2);二是 配置 token的具体实现方式为 JWT Token。

Spring Security安全配置 SpringSecurityConfig

@Configuration

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

@Override

@Bean

public AuthenticationManager authenticationManager() throws Exception {

return super.authenticationManager();

}

@Autowired

private UserDetailsService userDetailsService;

@Bean

public PasswordEncoder passwordEncoder() {

return new BCryptPasswordEncoder();

}

@Bean

public DaoAuthenticationProvider authenticationProvider() {

DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();

authenticationProvider.setUserDetailsService(userDetailsService);

authenticationProvider.setPasswordEncoder(passwordEncoder());

authenticationProvider.setHideUserNotFoundExceptions(false);

return authenticationProvider;

}

@Override

protected void configure(HttpSecurity http) throws Exception {

http

.requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**")

.and()

.authorizeRequests()

.antMatchers("/oauth/**").authenticated()

.and()

.formLogin().permitAll();

}

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.authenticationProvider(authenticationProvider());

}

}

客户端应用创建和配置

本文创建两个客户端应用:codesheep-client1 和codesheep-client2,由于两者类似,因此只以其一为例进行讲解

SSO客户端应用配置类 ClientWebsecurityConfigurer

@Override

public void configure(HttpSecurity http) throws Exception {

http.antMatcher("/**").authorizeRequests()

.anyRequest().authenticated();

}

}

复杂的东西都交给注解了!

application.yml配置

auth-server: http://localhost:8085/uac

server:

port: 8086

security:

oauth2:

client:

client-id: sheep1

client-secret: 123456

user-authorization-uri: ${auth-server}/oauth/authorize

access-token-uri: ${auth-server}/oauth/token

resource:

jwt:

key-uri: ${auth-server}/oauth/token_key

这里几项配置都非常重要,都是需要和前面搭建的授权中心进行通信的

创建测试控制器 TestController

@RestController

public class TestController {

@GetMapping("/normal")

@PreAuthorize("hasAuthority('ROLE_NORMAL')")

public String normal( ) {

return "normal permission test success !!!";

}

@GetMapping("/medium")

@PreAuthorize("hasAuthority('ROLE_MEDIUM')")

public String medium() {

return "medium permission test success !!!";

}

@GetMapping("/admin")

@PreAuthorize("hasAuthority('ROLE_ADMIN')")

public String admin() {

return "admin permission test success !!!";

}

}

此测试控制器包含三个接口,分别需要三种权限(ROLE_NORMAL、ROLE_MEDIUM、ROLE_ADMIN),待会后文会一一测试看效果

实验验证

启动授权认证中心 codesheep-server(启动于本地8085端口)

启动客户端应用 codesheep-client1 (启动于本地8086端口)

启动客户端应用 codesheep-client2 (启动于本地8087端口)

首先用浏览器访问客户端1 (codesheep-client1) 的测试接口:localhost:8086/normal,由于此时并没有过用户登录认证,因此会自动跳转到授权中心的登录认证页面:http://localhost:8085/uac/login:

![](https://s1.51cto.com/images/blog/201905/07/95f2c5660545deea5998d79ab67e831f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

![](https://s1.51cto.com/images/blog/201905/07/1110eb56499a673f4ea2edd404fa683a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

![](https://s1.51cto.com/images/blog/201905/07/9b6c8a7647900c9b1be37d085d5bfd08.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

![](https://s1.51cto.com/images/blog/201905/07/856b231c3a171270aa8fa0876f93ef3a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

这就验证了单点登录SSO的功能了!

java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践相关推荐

  1. 基于Spring Security + OAuth2 的SSO单点登录(服务端)

    相关技术 spring security: 用于安全控制的权限框架 OAuth2: 用于第三方登录认证授权的协议 JWT:客户端和服务端通信的数据载体 传统登录 登录web系统后将用户信息保存在ses ...

  2. 基于Spring Security OAuth2的SSO(单点登录)

    1. Theories What is SSO? 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一 ...

  3. java招投标网站源码_基于jsp的招标系统-JavaEE实现招标系统 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的招标系统, 该项目可用各类java课程设计大作业中, 招标系统的系统架构分为前后台两部分, 最终实现在线上进行招标 ...

  4. java婚庆网站源码_基于jsp的婚庆网站-JavaEE实现婚庆网站 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的婚庆网站, 该项目可用各类java课程设计大作业中, 婚庆网站的系统架构分为前后台两部分, 最终实现在线上进行婚庆 ...

  5. java 抽奖系统源码_基于jsp的抽奖系统-JavaEE实现抽奖系统 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的抽奖系统, 该项目可用各类java课程设计大作业中, 抽奖系统的系统架构分为前后台两部分, 最终实现在线上进行抽奖 ...

  6. 文件管理系统源码_基于Spring Cloud微服务构建多平台功能完善小说弹幕网站源码分享...

    致力于打造一个完整的可商用.可学习的小说门户平台,重新进行了数据库设计.代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性. 是一个多平台(web.安卓app.微信小程序).功能完善 ...

  7. java资产管理系统源码_基于jsp的资产管理系统-JavaEE实现资产管理系统 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的资产管理系统, 该项目可用各类java课程设计大作业中, 资产管理系统的系统架构分为前后台两部分, 最终实现在线上 ...

  8. python登录界面源码_基于Python的自媒体小助手---登录页面的实现代码

    核心技术:Python3.7 GUI技术:Tkinter (Python已经内置) 好多文章写Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 我看了N遍也没够好多东西都没有就基 ...

  9. 招聘管理系统软件java源码_基于Spring Boot的java开源招聘源码-铭阳招聘管理系统...

    铭阳招聘管理系统 铭阳招聘管理系统,采用流行的框架Spring Boot+mybatis+ehcache开发,实现了权限管理,solr全文搜索引擎,系统具执行效率高.模板自由切换.后台管理功能灵活等诸 ...

最新文章

  1. Cocos2d-x3.2 场景的生命周期
  2. java 提供的排序方法_请给出java几种排序方法
  3. 安装 | OpenCV4.2.0 + VS2017安装教程
  4. C++ 虚基类和抽象类关系
  5. 别做码农了,去做一名工程师
  6. mAP提升40%!YOLO3改进版—— Poly-YOLO:更快,更精确的检测和实例分割
  7. [常用]MySQL管理工具和应用程序
  8. 零基础自学Java要多久,是不是很难?
  9. Matlab R2017的下载与安装详细教程以及软件的学习资源
  10. ArcGIS利用DEM提取河流水系
  11. Flink中水位线Watermark
  12. C#反射基础知识实例总结
  13. 宝塔面板搭建方维直播图文教程
  14. web zxr10 中兴 路由器_中兴 ZXR10与思科路由器互联问题-路由器
  15. android 官方ui库,腾讯出品的一个超棒的 Android UI 库
  16. python 读取传入参数
  17. Android 10获取手机相册照片变成白色空白
  18. 微信小程序支付退款功能
  19. C# 类似PS的魔棒工具(1)
  20. 【数据应用技巧】基于快速GeoHash,实现海量商品与商圈的高效匹配

热门文章

  1. java TreeMap 源代码分析 平衡二叉树
  2. 正则表达式模式修正符
  3. 如何手撸一个较为完整的RPC框架
  4. 8种常被忽视的SQL错误用法,快来认领一下!
  5. 职场PUA到底有多可怕?
  6. 全民捡破烂,转转和闲鱼谁能胜出?
  7. 软件项目随着数据量的不断增加,有什么优化方案么?
  8. CTO让我研究中台(一):阿里的“数据+业务”双中台架构
  9. 聊聊这道【快手】面试题
  10. 关于Kafka Spring Boot的教程