0


SpringBoot Security OAuth2实现单点登录SSO(附源码)

在这里插入图片描述

文章目录

更多相关内容可查看

附源码地址:https://gitee.com/its-a-little-bad/SSO.git

基础概念

Spring Boot Security 和 OAuth2 结合实现单点登录(SSO)功能主要涉及以下几个方面:

1. 用户认证

OAuth2 允许用户使用第三方认证提供者(如Google、GitHub等)的凭据进行认证,而不需要在你的应用中存储用户的密码。Spring Security 的 oauth2Login() 配置确保了在用户进行 OAuth2 认证后,他们将被重定向回你的应用程序并得到授权。
具体实现了:

  • 用户点击登录按钮,选择使用 Google、GitHub 等作为认证提供者。
  • 应用程序重定向用户到选择的认证提供者的登录页面。
  • 用户在认证提供者的页面上输入凭据(用户名密码或其他认证方式)进行身份验证。
  • 认证成功后,认证提供者重定向用户回到你的应用程序,并且带有授权码。
  • 应用程序使用授权码交换令牌,并获取用户信息,从而进行用户认证。

2. 单点登录(SSO)

如果在你的应用程序中配置了多个 OAuth2 客户端(例如同时配置了 Google 和 GitHub),用户在其中一个认证成功后,在访问其他配置的客户端时不需要重新认证。这是 OAuth2 的一个核心优势之一,实现了单点登录(SSO)功能。
具体实现了:

  • 用户首次使用某个 OAuth2 客户端进行登录认证后,应用程序会创建一个本地的用户会话。
  • 当用户访问其他受保护的端点时,应用程序会检查用户的会话状态并自动完成认证流程,而无需用户再次提供凭据。

3. 授权管理

OAuth2 除了用于认证外,还提供了授权机制。通过配置 scope,你可以限制第三方应用程序可以访问的用户信息范围。在实现中,你可以根据具体需求设置不同的 scope,来控制第三方应用程序的访问权限。
具体实现了:

  • 在 OAuth2 客户端配置中,通过设置 scope 来限制第三方应用程序可以请求的用户信息。
  • 应用程序根据 OAuth2 提供者返回的用户信息,对用户的权限和访问进行管理和控制。

4. 安全性和配置

Spring Security 提供了强大的安全特性,例如 CSRF 保护、会话管理、角色授权等。通过合理配置,你可以确保你的应用程序在实现单点登录功能的同时,也保持了高级别的安全性。
具体实现了:

  • 在 SecurityConfig 中配置了安全规则,确保只有经过认证的用户才能访问受保护的端点。
  • 根据需要配置会话管理策略,例如限制用户同时登录的设备数量或时间。
网上摘的图,便于理解

个人理解:通俗点来说最好的例子就是微信在登陆别的app或者小程序可以进行微信授权类似的意思然后那个小程序你就无需在进行输入账号密码了

在这里插入图片描述

逻辑实现

配置认证服务器

注:你可以把他理解为上述所说的微信

1.依赖:所有依赖可以拉取git拉取

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-jose</artifactId></dependency>

2.application.yml配置 —需要配置自己的数据库信息,redis信息

spring:datasource:url: jdbc:mysql://localhost:3306/permission?serverTimezone=UTC
    username: root
    password:123456driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:show-sql:trueproperties:hibernate:dialect: org.hibernate.dialect.MySQL5Dialect
  session:store-type: redis
  redis:host: 127.0.0.1
    port:6379server:port:8080

3.配置OAuth2认证服务器–AuthorizationServerConfig文件

packagecom.cjs.sso.config;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Primary;importorg.springframework.security.core.token.DefaultToken;importorg.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;importorg.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;importorg.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;importorg.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;importorg.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;importorg.springframework.security.oauth2.provider.token.DefaultTokenServices;importorg.springframework.security.oauth2.provider.token.TokenStore;importorg.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;importorg.springframework.security.oauth2.provider.token.store.JwtTokenStore;importjavax.sql.DataSource;/**
 * @author twl
 * @date
 */@Configuration// 声明这是一个配置类@EnableAuthorizationServer// 开启授权服务器功能publicclassAuthorizationServerConfigextendsAuthorizationServerConfigurerAdapter{@Autowired// 自动注入数据源privateDataSource dataSource;@Override// 配置授权服务器的安全性,允许表单认证publicvoidconfigure(AuthorizationServerSecurityConfigurer security)throwsException{
        security.allowFormAuthenticationForClients();
        security.tokenKeyAccess("isAuthenticated()");}@Override// 配置客户端详情服务,客户端的信息将通过数据库来进行存储publicvoidconfigure(ClientDetailsServiceConfigurer clients)throwsException{
        clients.jdbc(dataSource);}@Override// 配置授权服务器端点的配置器,主要是一些非安全相关的配置,比如token存储、token自定义、授权模式等publicvoidconfigure(AuthorizationServerEndpointsConfigurer endpoints)throwsException{
        endpoints.accessTokenConverter(jwtAccessTokenConverter());
        endpoints.tokenStore(jwtTokenStore());//        endpoints.tokenServices(defaultTokenServices());}/*@Primary  // 设置为主要的,优先使用的
    @Bean  // 声明一个Bean
    public DefaultTokenServices defaultTokenServices() {  // 默认的token服务
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(jwtTokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }*/@Bean// 声明一个BeanpublicJwtTokenStorejwtTokenStore(){// JWT的token存储对象returnnewJwtTokenStore(jwtAccessTokenConverter());}@Bean// 声明一个BeanpublicJwtAccessTokenConverterjwtAccessTokenConverter(){// JWT的token转换器JwtAccessTokenConverter jwtAccessTokenConverter =newJwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey("cjs");//  设置JWT签名密钥return jwtAccessTokenConverter;}}

配置Spring Security

packagecom.cjs.sso.config;importcom.cjs.sso.service.MyUserDetailsService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.builders.WebSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;importorg.springframework.security.crypto.password.PasswordEncoder;/**
 * @author twl
 * @date 
 */@Configuration// 声明这是一个配置类@EnableWebSecurity// 开启Web安全功能publicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@Autowired// 自动注入用户详情服务privateMyUserDetailsService userDetailsService;@Override// 配置身份验证管理器protectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Override// 配置Web安全,忽略对于静态资源的安全控制publicvoidconfigure(WebSecurity web)throwsException{
        web.ignoring().antMatchers("/assets/**","/css/**","/images/**");}@Override// 配置Http安全,包括登录页面、登录请求路径、其他请求的安全控制等protectedvoidconfigure(HttpSecurity http)throwsException{
        http.formLogin().loginPage("/login")// 设置登录页面的路径.and().authorizeRequests().antMatchers("/login").permitAll()// 对登录页面的请求不进行安全控制.anyRequest().authenticated()// 对其他所有请求都进行安全控制,必须通过身份验证.and().csrf().disable().cors();// 禁用CSRF保护,启用跨域资源共享}@Bean// 声明一个BeanpublicPasswordEncoderpasswordEncoder(){// 密码编码器,用于对密码进行编码returnnewBCryptPasswordEncoder();}}

两个客户端

注:可以理解为两个微信小程序,可以通过微信进行授权登陆

1.application.yml配置

server:
  port:8082
  servlet:
    context-path:/memberSystem
security:
  oauth2:
    client:
      client-id:UserManagement
      client-secret: user123
      access-token-uri: http://localhost:8080/oauth/token
      user-authorization-uri: http://localhost:8080/oauth/authorize
    resource:
      jwt:
        key-uri: http://localhost:8080/oauth/token_key
server:
  port:8083
  servlet:
    context-path:/orderSystem
security:
  oauth2:
    client:
      client-id:OrderManagement
      client-secret: order123
      access-token-uri: http://localhost:8080/oauth/token
      user-authorization-uri: http://localhost:8080/oauth/authorize
    resource:
      jwt:
        key-uri: http://localhost:8080/oauth/token_key

2.添加依赖

<dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.1.3.RELEASE</version></dependency>

3.配置安全策略–WebSecurityConfig文件

创建并配置Spring Security以确保所有请求都经过Token验证:
packagecom.cjs.example.config;importcom.cjs.example.util.EnvironmentUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.builders.WebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/**
 * @author twl
 * @date 
 */@EnableOAuth2Sso@ConfigurationpublicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@AutowiredprivateEnvironmentUtils environmentUtils;@Overridepublicvoidconfigure(WebSecurity web)throwsException{
        web.ignoring().antMatchers("/bootstrap/**");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{if("local".equals(environmentUtils.getActiveProfile())){
            http.authorizeRequests().anyRequest().permitAll();}else{
            http.logout().logoutSuccessUrl("http://localhost:8080/logout").and().authorizeRequests().anyRequest().authenticated().and().csrf().disable();}}}
packagecom.cjs.example.config;importorg.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/**
 * @author twl
 * @date
 */@EnableOAuth2Sso@ConfigurationpublicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{
        http.logout().logoutSuccessUrl("http://localhost:8080/logout");
        http.authorizeRequests().anyRequest().authenticated();
        http.csrf().disable();}}

页面展示

进入http://localhost:8080/登陆页面–点击登陆进行授权

在这里插入图片描述

授权完登陆跳转页面

在这里插入图片描述

直接访问http://localhost:8082/memberSystem/member/list

在这里插入图片描述

本篇小结

如果直接访问http://localhost:8082/memberSystem/member/list 也会自动跳转到http://localhost:8080/登陆界面,进行上述整篇都在说的认证服务器,但如果先登录认证服务器,在进行登陆8082端口这个服务,会直接进入8082页面,这就是所谓的已经授权过的无需在重复登陆的实现

这样描述大家应该都比较好理解了,这个无需自己敲其实,知道怎么实现的,面试能聊个大概即可,毕竟工作中很少会去做这个事情

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/Aaaaaaatwl/article/details/140492824
版权归原作者 来一杯龙舌兰 所有, 如有侵权,请联系我们删除。

“SpringBoot Security OAuth2实现单点登录SSO(附源码)”的评论:

还没有评论