一,sso的用途 ?

1,如果有多个应用系统,用户只需要登录一次就可以访问所有相互信任的应用系统。
不需要每次输入用户名称和用户密码,
也不需要创建并记忆多套用户名称和用户密码。

2,系统管理员只需维护一套统一的用户账号,方便、简单。
而不必管理很多套的用户账号。

3, 如果需要开发新的应用系统,可以直接使用单点登录平台的用户认证服务,简化开发流程。

4,oauth和sso的区别:

oauth2解决的是服务提供方(微信等)给第三方应用授权的问题,
   sso解决的是大型系统中各个子系统如何共享登陆状态的问题

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,演示项目的相关信息

1,项目地址:

https://github.com/liuhongdi/securityssojwt

2,功能说明:

演示了基于oauth2实现sso

3,项目结构:如图:

三,配置文件说明

1,ssoserver的 pom.xml

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--oauth2-->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
<!--jwt-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.1.RELEASE</version>
</dependency> <!--jaxb-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>

2,ssoclient1的 pom.xml

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--oauth2-->
<dependency><groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
<!--jwt-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
<!--oauth2 autoconfigure-->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>

3,ssoclient2的 pom.xml

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--oauth2-->
<dependency><groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
<!--jwt-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
<!--oauth2 autoconfigure-->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>

4,ssoserver的application.properties

server.port = 8080
server.servlet.context-path = /server
spring.security.user.password=123456 #error
server.error.include-stacktrace=always
#log
logging.level.org.springframework.web=trace
logging.level.org.springframework.security=debug

5,ssoclient1的application.properties

security.oauth2.client.client-id=client1
security.oauth2.client.client-secret=client1secrect
#需要认证时候跳转的地址
security.oauth2.client.user-authorization-uri=http://127.0.0.1:8080/server/oauth/authorize
#请求令牌地址
security.oauth2.client.access-token-uri=http://127.0.0.1:8080/server/oauth/token
#解析
security.oauth2.resource.jwt.key-uri=http://127.0.0.1:8080/server/oauth/token_key
#security.oauth2.resource.jwt.key-value=imooc
#sso
server.port=8081
server.servlet.context-path=/client1

6,ssoclient2的application.properties

security.oauth2.client.client-id=client2
security.oauth2.client.client-secret=client2secrect
#需要认证时候跳转的地址
security.oauth2.client.user-authorization-uri=http://127.0.0.1:8080/server/oauth/authorize
#请求令牌地址
security.oauth2.client.access-token-uri=http://127.0.0.1:8080/server/oauth/token
#解析
security.oauth2.resource.jwt.key-uri=http://127.0.0.1:8080/server/oauth/token_key
#sso
server.port=8082
server.servlet.context-path=/client2

四,java代码说明:

1,ssoserver的WebSecurityConfig.java

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Resource
private SsoUserDetailsService ssoUserDetailsService; @Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(ssoUserDetailsService).passwordEncoder(passwordEncoder());
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().authorizeRequests().anyRequest().authenticated();
}
}

2,ssoserver的SsoUserDetailsService.java:

@Component
public class SsoUserDetailsService implements UserDetailsService { @Autowired
private PasswordEncoder passwordEncoder; //本来应该从数据库加载数据,此处供仅演示
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("----------------------loadUserByUsername");
if (username.equals("laoliu") == false) {
throw new UsernameNotFoundException("用户名不存在");
}
return new User(username, passwordEncoder.encode("123456"),
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
}

3,ssoserver的SsoAuthorizationServerConfig.java:

@Configuration
@EnableAuthorizationServer
public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { //配置供访问的客户端的账户
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
// 注册一个客户端,设置名称
.withClient("client1")
// 设置客户端阴匙
.secret(new BCryptPasswordEncoder().encode("client1secrect"))
// 对应客户端登录请求URI
.redirectUris("http://127.0.0.1:8081/client1/login")
// 授权方式
.authorizedGrantTypes("authorization_code", "password", "refresh_token")
// 授权范围
.scopes("all")
// 是否自动同意,如果采用非自动同意,则需要用户手动授权
.autoApprove(true)
.and().
withClient("client2")
.redirectUris("http://127.0.0.1:8082/client2/login")
.secret(new BCryptPasswordEncoder().encode("client2secrect"))
.authorizedGrantTypes("authorization_code", "password", "refresh_token")
.scopes("all")
.autoApprove(true);
} @Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
} @Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("isAuthenticated()");
} @Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
} @Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
//指定signkey
converter.setSigningKey("liuhongdi");
return converter;
}
}

4,ssoclient1的HomeController.java

@Controller
@RequestMapping("/home")
public class HomeController {
//查看登录后的用户信息
@RequestMapping("/session")
@ResponseBody
public String getsession(){
//session
String userone = SessionUtil.getCurrentUserName();
System.out.println("user:"+userone);
if (userone == null) {
return "not login";
} else {
return userone;
}
}
}

5,ssoclient1的SessionUtil.java

public class SessionUtil {
//得到security所保存的用户
public static String getCurrentUserName(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) {
Object principal = authentication.getPrincipal();
//System.out.println(principal);
if (principal instanceof String) {
return (String)principal;
} else if (principal instanceof UserDetails) {
String currentuser = ((UserDetails) principal).getUsername();
return currentuser;
} else {
//System.out.println("not instanceof UserDetails");
}
return null;
}
return null;
}
}

6,其他非关键代码可访问github查看

五,测试效果

1,按以下顺序启动三个模块:

ssoserver

ssoclient1

ssoclient2

2,先访问client1,

http://127.0.0.1:8081/client1/home/session

会跳转到:

http://127.0.0.1:8080/server/login

如图:

我们输入用户名 laoliu,密码 123456

这个是写死在代码中的演示账号

登录后会跳转到:

这个url会打印当前登录用户的用户名

我们新打开一个标签页:

http://127.0.0.1:8082/client2/home/session

我们之前并未从client2登录,查看效果:

可以看到也已经登录

3,通过html页面跳转访问:

http://127.0.0.1:8081/client1/index.html

返回:

点击 访问client2 的链接

可正常访问

六,查看spring boot版本

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.3.RELEASE)

spring boot:spring security+oauth2+sso+jwt实现单点登录(spring boot 2.3.3)的更多相关文章

  1. 使用Spring Security OAuth2进行简单的单点登录

    1.概述 在本教程中,我们将讨论如何使用Spring Security OAuth和Spring Boot实现SSO - 单点登录. 我们将使用三个单独的应用程序: 授权服务器 - 这是中央身份验证机 ...

  2. Spring Security OAuth2 SSO

    通常公司肯定不止一个系统,每个系统都需要进行认证和权限控制,不可能每个每个系统都自己去写,这个时候需要把登录单独提出来 登录和授权是统一的 业务系统该怎么写还怎么写 最近学习了一下Spring Sec ...

  3. Spring Security OAuth2 SSO 单点登录

    基于 Spring Security OAuth2 SSO 单点登录系统 SSO简介 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自 ...

  4. 基于spring boot2.0+spring security +oauth2.0+ jwt微服务架构

    github地址:https://github.com/hankuikuide/microservice-spring-security-oauth2 项目介绍 该项目是一个演示项目,主要演示了,基于 ...

  5. 【SpringSecurityOAuth2】源码分析@EnableOAuth2Sso在Spring Security OAuth2 SSO单点登录场景下的作用

    目录 一.从Spring Security OAuth2官方文档了解@EnableOAuth2Sso作用 二.源码分析@EnableOAuth2Sso作用 @EnableOAuth2Client OA ...

  6. Spring Security构建Rest服务-1300-Spring Security OAuth开发APP认证框架之JWT实现单点登录

    基于JWT实现SSO 在淘宝( https://www.taobao.com )上点击登录,已经跳到了 https://login.taobao.com,这是又一个服务器.只要在淘宝登录了,就能直接访 ...

  7. springBoot整合spring security+JWT实现单点登录与权限管理--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  8. SSO之CAS单点登录详细搭建教程

    本教程是我个人编写,花费几个小时的时间,给需要学习的人员学习使用,希望能帮助到你们. [环境说明]:本文演示过程在同一个机器上的(也可以在三台实体机器或者三个的虚拟机上),环境如下: windows7 ...

  9. Spring Cloud:Security OAuth2 自定义异常响应

    对于客户端开发或者网站开发而言,调用接口返回有统一的响应体,可以针对性的设计界面,代码结构更加清晰,层次也更加分明. 默认异常响应 在使用 Spring Security Oauth2 登录和鉴权失败 ...

随机推荐

  1. Keepalived之高可用LVS集群

    前文我们聊了下keepalived的邮件通知相关配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13645163.html:今天我们来说说keepalive ...

  2. 安卓自动化测试工具Monkey简单使用

    一.首先安装adb 地址:http://www.downza.cn/soft/219906.html安装到D盘下,安装的过程中自己注意下不要安装上全家桶.找到这个压缩包:解压到当前文件夹: 二.将ad ...

  3. C语言01

    从问题到C语言程序设计 1.1计算机的问题求解方法 程序设计面向的问题 什么问题可以用程序的方法解决? 打印九九乘法表 图形变换 文件压缩问题 ....... 一切可计算的问题 如何解决? 确定问题可 ...

  4. 技术解析丨C++元编程之Parser Combinator

    摘要:借助C++的constexpr能力,可以轻而易举的构造Parser Combinator,对用户定义的字符串(User defined literal)释放了巨大的潜力. ## 引子 前不久在C ...

  5. C# NX二次开发环境搭建

    在网上看到一篇C#二次开发环境搭建的文章:NX二次开发-使用NXOPEN C#手工搭建开发环境配置 ,写得非常好.我按照文章操作,过程中遇到几个问题,把问题分享给大家,希望对各位有帮助. 注意三点: ...

  6. 报表工具FastReport VCL 最新版发布!

    新功能 为主要包类添加了类引用 在报表设计器中添加了SQL编辑器的自定义 为TfrxReport的操作添加了延迟的命令池:PrepareReport,ShowReport,LoadFrom.可以调用R ...

  7. Python练习题 031:Project Euler 003:最大质因数

    本题来自 Project Euler 第3题:https://projecteuler.net/problem=3 # Project Euler: Problem 3: Largest prime ...

  8. 093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 03 static关键字(下)

    093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  9. 039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述

    039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述 本文知识点:循环结构概述 循环结构主要内容 while 循环 do-whiile ...

  10. 001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学

    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学 welcome to Java World 欢迎来到Java世界 一起领略Java编程世界的奥秘与奥妙 ...