基于 Spring Security OAuth2 SSO 单点登录系统

SSO简介

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一退出(single sign-off)就是指,只需要单一的退出动作,就可以结束对于多个系统的访问权限。

Spring Security OAuth

Spring Security OAuth使用标准的Spring和Spring Security编程模型和配置惯例,为使用Spring Security with OAuth(1a)和OAuth2提供支持。OAuth协议

案例介绍

此工程分为三个模块:授权服务器(sso-auth-server)、web应用a(sso-client-a)、web应用b(sso-client-b),想达到的目的是:某一个用户在a系统登陆后在跳往b系统后不用在重复登录。

  • sso-auth-server:

    • pom:
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
    </dependency>
    </dependencies>
    • yml:
    server:
    port: 8082
    context-path: /auth_server
    • SsoServerApplication.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @SpringBootApplication
    public class SsoServerApplication { public static void main(String[] args) {
    SpringApplication.run(SsoServerApplication.class, args);
    } /**
    * 为测试环境添加相关的 Request Dumper information,便于调试
    *
    * @return
    */
    @Profile("!cloud")
    @Bean
    RequestDumperFilter requestDumperFilter() {
    return new RequestDumperFilter();
    } }
    • userDetailsService.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @Component
    public class SsoUserDetailsService implements UserDetailsService { @Autowired
    private PasswordEncoder passwordEncoder; @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    return new User(username, passwordEncoder.encode("admin"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
    }
    }
    • SsoSecurityConfig.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @Configuration
    public class SsoSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired
    private UserDetailsService userDetailsService; @Bean
    public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
    } @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
    .and().authorizeRequests()
    .antMatchers("/**/*.js", "/**/*.css", "/**/*.jpg", "/**/*.png")
    .permitAll()
    .anyRequest().authenticated()
    .and()
    .csrf().disable();
    // http.formLogin().and().authorizeRequests().anyRequest().authenticated();
    } @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    }
    • SsoAuthServerConfig.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @Configuration
    @EnableAuthorizationServer
    public class SsoAuthServerConfig extends AuthorizationServerConfigurerAdapter { /**
    * 客户端一些配置
    *
    * @param clients
    * @throws Exception
    */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
    .withClient("client1")
    .secret("secret1")
    .authorizedGrantTypes("authorization_code", "refresh_token")
    .scopes("all", "read", "write")
    .autoApprove(true)
    .and()
    .withClient("client2")
    .secret("secret2")
    .authorizedGrantTypes("authorization_code", "refresh_token")
    .scopes("all", "read", "write")
    .autoApprove(true);
    } /**
    * 配置jwtTokenStore
    *
    * @param endpoints
    * @throws Exception
    */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
    } /**
    * springSecurity 授权表达式
    *
    * @param security
    * @throws Exception
    */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.tokenKeyAccess("isAuthenticated()");
    } /**
    * JwtTokenStore
    *
    * @return
    */
    @Bean
    public TokenStore jwtTokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
    } /**
    * 生成JTW token
    *
    * @return
    */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey("andy");
    return converter;
    }
    }
  • sso-client-a

    • pom:
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
    </dependency> </dependencies>
    • yml:
    server:
    port: 8080
    context-path: /clienta
    security:
    oauth2:
    client:
    clientId: client1
    clientSecret: secret1
    access-token-uri: http://127.0.0.1:8082/auth_server/oauth/token #请求令牌的地址
    user-authorization-uri: http://127.0.0.1:8082/auth_server/oauth/authorize #请求认证的地址
    resource:
    jwt:
    key-uri: http://127.0.0.1:8082/auth_server/oauth/token_key #解析jwt令牌所需要密钥的地址
    • index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>sso-client-A</title>
    </head>
    <body>
    <h1>sso demo client-A</h1>
    <a href="http://127.0.0.1:8081/clientb/index.html">访问client-b</a>
    </body>
    </html>
    • SsoClientA.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @EnableOAuth2Sso
    @SpringBootApplication
    public class SsoClientA {
    public static void main(String[] args) {
    SpringApplication.run(SsoClientA.class, args);
    }
    }
  • sso-client-b

    • pom:
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    </dependency> <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
    </dependency> </dependencies>
    • yml:
    server:
    port: 8081
    context-path: /clientb
    security:
    oauth2:
    client:
    clientId: client2
    clientSecret: secret2
    access-token-uri: http://127.0.0.1:8082/auth_server/oauth/token
    user-authorization-uri: http://127.0.0.1:8082/auth_server/oauth/authorize
    resource:
    jwt:
    key-uri: http://127.0.0.1:8082/auth_server/oauth/token_key
    • index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>sso-client-B</title>
    </head>
    <body>
    <h1>sso demo client-B</h1>
    <a href="http://127.0.0.1:8080/clienta/index.html">访问client-a</a>
    </body>
    </html>
    • SsoClientA.java
    /**
    * @author Leone
    * @since 2018-05-07
    **/
    @RestController
    @EnableOAuth2Sso
    @SpringBootApplication
    public class SsoClientB { @Autowired
    private OAuth2RestTemplate oAuth2RestTemplate; public static void main(String[] args) {
    SpringApplication.run(SsoClientB.class, args);
    } @GetMapping("/user")
    public Authentication user(Authentication user) {
    return user;
    } @Bean
    public OAuth2RestTemplate oAuth2RestTemplate(OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails details){
    return new OAuth2RestTemplate(details,oAuth2ClientContext);
    }
    }

项目源码:git@github.com:janlle/sso-server.git

Spring Security OAuth2 SSO 单点登录的更多相关文章

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

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

  2. Spring Security OAuth2实现单点登录

    1.概述 在本教程中,我们将讨论如何使用 Spring Security OAuth 和 Spring Boot 实现 SSO(单点登录). 本示例将使用到三个独立应用 一个授权服务器(中央认证机制) ...

  3. SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统

    一.单点登录SSO介绍   目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的 ...

  4. Spring Security OAuth2 SSO

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

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

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

  6. spring boot:spring security+oauth2+sso+jwt实现单点登录(spring boot 2.3.3)

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

  7. Spring Security安全以及单点登录

    1.单点登录:多个系统,只需在一个系统登录以后,其他系统可以直接访问. 2.CAS(认证服务器),Apache Httpd,OpenLdap,OpenSSL(生成证书)几个工具实现 3.原理:登录通过 ...

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

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

  9. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

随机推荐

  1. opencv源码编写规则

    OPENCV作为一种开源的计算机视觉库,我们有必要去了解这个库的一些编码格式及文件结构. 1.文档命名规则 必须将所有功能放入一个或多个.cpp和.hpp文件到OpenCV的相应模块中,或者如果贡献的 ...

  2. cad2012卸载/安装失败/如何彻底卸载清除干净cad2012注册表和文件的方法

    cad2012提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装cad2012失败提示cad2012安装未完成,某些产品无法安装,也有时候想重新安装cad2012 ...

  3. OkHttp 入门篇

    OkHttp是一个HTTP & HTTP2的客户端,能够用来进行Android 和 Java 开发. HTTP是现代应用的最基本的网络环境.让你的HTTP更加有效的工作能够让你的东西加载更快而 ...

  4. Javascript高级编程学习笔记(11)—— 垃圾回收机制

    垃圾回收机制 垃圾回收机制,是保证脚本能长时间运行的重要机制 JS具有自动垃圾收集机制,也就是说执行环境会负责管理代码执行过程中使用的内存 与一些偏底层的语言(c.c++)不同,我们不需要手工地去管理 ...

  5. 1.viewpager

    ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view. ViewPager类直接继承了ViewGroup类,所以它是一个容器类,可以在其中添加其他的view类. ...

  6. consul初步学习

    简介 consul是一个服务发现框架 类似的还有zookeeper,eureka,etcd等 作用 服务发现(service discovery) 健康检查(health checking) 配置存储 ...

  7. u-boot中debug的一些总结

    研究u-boot,首要搞清楚的是代码的流程,运行流程是什么样子的呢?不知道,就看log.这就要把log信息 打开.研究u-boot的文件,发现里面是很多DEBUG宏定义的打印,这个打印着怎么打开呢? ...

  8. Linux - 执行命令与脚本

    001 - Linux执行多条命令 方法1:在命令行下可以一次性粘贴多条语句,shell会依次执行并输出结果 方法2:在一个命令行中,用分号将各个命令隔开或者使用&&连接各个命令 示例 ...

  9. python网络编程初级

    网络编程的专利权应该属于Unix,各个平台(如windows.Linux等).各门语言(C.C++.Python.Java等)所实现的符合自身特性的语法都大同小异.在我看来,懂得了Unix的socke ...

  10. Java 11 快要来了,编译 & 运行一个命令搞定!

    Java 11 马上要来了,原定于 9 月发布,还有不到 3 个月了,敬请期待更多新功能被加入到 11 当中,本文本讲的是 JEP 330 这个新特性. 化繁为简,一个命令编译运行源代码 看下面的代码 ...