Spring Security 自定义授权服务器实践

【Spring Authorization Server 系列】(一)入门篇,快速搭建一个授权服务器 Spring Authorization Server是一个框架,提供了OAuth2.1和OpenIDConnect1.0规范以及其他相关规范的实现。它建立在SpringSecurity之上,为构建OpenIDConnect1.0IdentityProviders和OAuth2AuthorizationServer产品提供安全、轻量级和可定制的基础。旧版的框架是,该框架已停止维护。SpringSecurityOAuth2认证/授权服务器的前世今生。............... 阅读详情

授权服务器变迁

授权服务器(Authorization Server)目前并没有集成在Spring Security项目中,而是作为独立项目存在于Spring生态中,图1为Spring Authorization Server 在Spring 项目列表中的位置。

Spring Authorization Server 为什么没被集成在Spring Security中呢?

起因是因为Spring 中的Spring Security OAuth、Spring Cloud Security都对OAuth有自己的实现,Spring团队开始是想把OAuth独立出来放到Spring Security中,但是后面Spring团队意识到OAuth授权服务并不适合包含在Spring Security框架中,于是在2019年11月Spring宣布不在Spring Security中支持授权服务器。

但是对于Spring Security不再支持授权服务器,社区反应强烈。于是在2020年4月,Spring推出了Spring Authorization Server项目。

目前项目最新GA版本为0.3 GA,预览版本1.0.0-M1。

最小化配置

安装授权服务器

1、新创建一个Spring Boot项目,命名为 spring-security-authorization-server
2、引入pom依赖

<pre class="prettyprint hljs xml" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;"><dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>0.3.1</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

配置授权服务器

<pre class="prettyprint hljs livescript" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.RequestMatcher;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;

@Configuration(proxyBeanMethods = false)
public class  AuthorizationServerConfig  { 

    //授权端点过滤器链  @Bean  @Order(Ordered.HIGHEST_PRECEDENCE)  public  SecurityFilterChain  authorizationServerSecurityFilterChain(HttpSecurity http)  throws  Exception  {  OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =  new  OAuth2AuthorizationServerConfigurer<>();  RequestMatcher endpointsMatcher = authorizationServerConfigurer .getEndpointsMatcher(); http //没有认证会自动跳转到/login页面
                .exceptionHandling((exceptions)  -> exceptions .authenticationEntryPoint(  new  LoginUrlAuthenticationEntryPoint("/login"))  )  .requestMatcher(endpointsMatcher)  .authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated()  )  .csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))  .apply(authorizationServerConfigurer);  return http.build();  }  //用于身份验证的过滤器链  @Bean  @Order(2)  public  SecurityFilterChain  defaultSecurityFilterChain(HttpSecurity http)  throws  Exception  { http .authorizeHttpRequests((authorize)  -> authorize .anyRequest().authenticated()  )  .formLogin(Customizer.withDefaults());  return http.build();  }  //配置主体用户  @Bean  public  UserDetailsService  userDetailsService()  {  UserDetails userDetails =  User.withDefaultPasswordEncoder()  .username("user")  .password("user")  .roles("USER")  .build();  return  new  InMemoryUserDetailsManager(userDetails);  }  //注册客户端  @Bean  public  RegisteredClientRepository  registeredClientRepository()  {  RegisteredClient registeredClient =  RegisteredClient.withId(UUID.randomUUID().toString())  //客户端id  .clientId("testClientId")  //客户端秘钥,授权服务器需要加密存储  .clientSecret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("testClientSecret"))  //授权方法  .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)  //支持的授权类型  .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)  .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)  .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)  //回调地址,支持多个,本地测试不能使用localhost  .redirectUri("http://127.0.0.1:8080/login/oauth2/code/customize")  .scope(OidcScopes.OPENID)  //授权scope  .scope("message.read")  .scope("userinfo")  .scope("message.write")  //是否需要授权页面,开启跳转到授权页面,需要手动确认  .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())  .build();  return  new  InMemoryRegisteredClientRepository(registeredClient);  }  //token加密  @Bean  public  JWKSource<SecurityContext>  jwkSource()  {  KeyPair keyPair =  generateRsaKey();  RSAPublicKey publicKey =  (RSAPublicKey) keyPair.getPublic();  RSAPrivateKey privateKey =  (RSAPrivateKey) keyPair.getPrivate();  RSAKey rsaKey =  new  RSAKey.Builder(publicKey)  .privateKey(privateKey)  .keyID(UUID.randomUUID().toString())  .build();  JWKSet jwkSet =  new  JWKSet(rsaKey);  return  new  ImmutableJWKSet<>(jwkSet);  }  private  static  KeyPair  generateRsaKey()  {  KeyPair keyPair;  try  {  KeyPairGenerator keyPairGenerator =  KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); keyPair = keyPairGenerator.generateKeyPair();  }  catch  (Exception ex)  {  throw  new  IllegalStateException(ex);  }  return keyPair;  }  //配置协议端点,比如/oauth2/authorize、/oauth2/token等  @Bean  public  ProviderSettings  providerSettings()  {  return  ProviderSettings.builder().build();  }  }

如上是最小化授权服务器的配置,这里我们将授权主体和客户端都存储在内存中,当然也可以持久化到数据库中,分别使用 JdbcUserDetailsManager 、 JdbcRegisteredClientRepository 。

ProviderSettings.builder().build() 使用了默认的配置,这几个地址我们后面就会用到:

<pre class="prettyprint hljs less" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">public static Builder builder() { 
    return new Builder()
            .authorizationEndpoint("/oauth2/authorize")
            .tokenEndpoint("/oauth2/token")
            .jwkSetEndpoint("/oauth2/jwks")
            .tokenRevocationEndpoint("/oauth2/revoke")
            .tokenIntrospectionEndpoint("/oauth2/introspect")
            .oidcClientRegistrationEndpoint("/connect/register")
            .oidcUserInfoEndpoint("/userinfo");
}

:exclamation: 官方指出@Import(OAuth2AuthorizationServerConfiguration.class)也可以用来最小化配置,但我亲测这种方式没多大用处,并且还有问题。

配置客户端

这里我们要使用自己的搭建授权服务器,需要自定义一个客户端,还是使用前面集成GitHub的示例,只要在配置文件中扩展就可以。

完整配置如下:

<pre class="prettyprint hljs less" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">spring:
  security:
    oauth2:
      client:
        registration:
          gitee:
            client-id: gitee_clientId
            client-secret: gitee_secret
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            client-name: Gitee
          github:
            client-id: github_clientId
            client-secret: github_secret
          # 自定义
          customize:
            client-id: testClientId
            client-secret: testClientSecret
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            client-name: Customize
            scope:
              - userinfo
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-info-uri: https://gitee.com/api/v5/user
            user-name-attribute: name
          # 自定义
          customize:
            authorization-uri: http://localhost:9000/oauth2/authorize
            token-uri: http://localhost:9000/oauth2/token
            user-info-uri: http://localhost:9000/userinfo
            user-name-attribute: username

:exclamation: 在配置授权服务器uri的时候,请勿依旧使用127.0.0.1,由于是在本地测试,授权服务器的session和客户端的session会互相覆盖,导致莫名其妙的问题。

请区分回调地址,和授权服务器端点uri的地址。

客户端的session

授权服务器的session

另外为了能够更好的调式,可以在两个应用增加 @EnableWebSecurity(debug = true) 和 log日志,日志如下,打开 TRACE 级别日志:

<pre class="prettyprint hljs css" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: TRACE
    org.springframework.security.oauth2: TRACE

现在启动两个应用,访问 http://127.0.0.1:8080/hello ,自动跳转到登录页面。

点击 Customize ,将跳转至授权服务器,注意看地址栏地址为localhost:9000/login,输入 用户名/密码登录,user/user 。

登录后,将跳转至授权页面,由于我们没有定制,使用的是默认页面,可以看到该页面的地址为

http://localhost:9000/oauth2/authorize?response_type=code&client_id=testClientId&scope=userinfo&state=yV1ElAN2855yq3bY5kgj_rmilnCclyvZHkxVB7a1d84%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/customize 。

我们勾选userinfo,提交后即跳转回客户端。

我们看下客户收到的日志,授权服务器带着code回调了我们填写的回调地址。

Request received for GET '/login/oauth2/code/customize?code=DPAlx5uyrUpfrZIlBKrpIy_mmcgiyC2qCxPFtUeLA0fBrZd238XM2vN8M1jv9XAgl0KA-D54P_KzVH7RbUw7ApBUc2pbnuSVRZUyHazozmNM4YgQ06CZryfr20qLRhW4&state=_Sgak7GLILLKbwr9JVuwA2xVp95CWPgUMByQcvePkgM%3D'

<pre class="prettyprint hljs markdown" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">************************************************************

Request received for GET '/login/oauth2/code/customize?code=DPAlx5uyrUpfrZIlBKrpIy_mmcgiyC2qCxPFtUeLA0fBrZd238XM2vN8M1jv9XAgl0KA-D54P_KzVH7RbUw7ApBUc2pbnuSVRZUyHazozmNM4YgQ06CZryfr20qLRhW4&state=_Sgak7GLILLKbwr9JVuwA2xVp95CWPgUMByQcvePkgM%3D':

org.apache.catalina.connector.RequestFacade@1a8761d0

servletPath:/login/oauth2/code/customize
pathInfo:null
headers: 
host: 127.0.0.1:8080
connection: keep-alive
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: cross-site
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
sec-ch-ua: "Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
referer: http://127.0.0.1:8080/
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
cookie: JSESSIONID=2527F412F53FA27A30BFBC39161ABB63

Security filter chain: [
  DisableEncodeUrlFilter
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  CsrfFilter
  LogoutFilter
  OAuth2AuthorizationRequestRedirectFilter
  OAuth2AuthorizationRequestRedirectFilter
  OAuth2LoginAuthenticationFilter
  DefaultLoginPageGeneratingFilter
  DefaultLogoutPageGeneratingFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  OAuth2AuthorizationCodeGrantFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

Spring Security 的最小化授权服务器的配置,到这里结束了,该demo虽然代码量非常少,但涉及的知识非常多,并且坑也多。

Spring Security文档中的代码说明更新不及时,比如 @Import(OAuth2AuthorizationServerConfiguration.class) 文档中说明是最小化配置,但文档的 快速开始 又提供了另外一种的最小化配置方式。

另外授权服务器如果发生异常,是不会打印堆栈的,而是把错误信息放入到response中,是打算要在页面上显示,然而demo的默认错误页并不会显示错误详情,只有错误编号400,如图。

Spring Authorization Server 还需要多多完善,Spring Security也不例外,不久前我还提了一个PR,把一个持续数个版本的bug给修复了藍(过了,只是文档中的错误罢了,被标记为文档中的bug),看多了外国人的产品,其实也没有太比国内的开源项目好,坑也很多,而我们某些大厂的开源项目其实很好,却被网友门各种喷。

Spring Security OAuth2自定义异常处理:从认证原理到工程实践 在微服务架构与分布式系统中,认证与授权是保障应用安全的核心机制。OAuth2作为行业标准的授权框架,通过授权码、令牌等机制实现安全的资源访问委托。其原理在于分离资源所有者、客户端与资源服务器,通过令牌替代密码提升安全性。这一技术的核心价值在于为多系统集成、第三方登录提供标准化解决方案,广泛应用于单点登录、API开放平台等场景。然而,默认实现往往在令牌失效、客户端信息错误时返回晦涩的技术异常,影响用户体验与系统健壮性。本文聚焦于Spring Security OAuth2的异常处理机制,深入解析Authent 阅读详情

相关推荐

【Java】 Spring Security 赋能 OAuth 2.0:构建安全高效的现代认证体系

在当今数字化时代,认证与授权已成为应用系统安全的核心。OAuth 2.0 作为一种开放标准协议,广泛应用于第三方授权场景中,而 Spring Security 则提供了强大的框架支持来实现这一协议。本文深入探讨了如何利用 Spring Security 构建一个完整的 OAuth 2.0 认证系统,从 OAuth 2.0 的基本原理入手,详细阐述了授权服务器、资源服务器和客户端的配置与实现。文章结合实际代码示例,包括依赖引入、配置类编写、令牌生成与验证等关键步骤,并通过中文注释进行详细解释。同时,介绍了常见

一个被知识诅咒的人 1019

授权服务器框架Spring Authorization Server的过滤器链

上一篇我们初次体验了Spring Authorization Server,很多粉丝都希望对这个新授权框架有进一步了解。所以今天我们再进一步再从配置上来了解和OAuth2.0授权服务器相关...

码农小胖哥 5771

别再只会用第三方登录了!手把手教你用Spring Security OAuth2.0搭建自己的授权服务器

本文详细介绍了如何使用Spring Security OAuth2.0构建企业级授权服务器,从环境准备、核心配置到JWT令牌管理,逐步指导开发者搭建符合RFC标准的OAuth2.0授权服务。文章涵盖了授权流程测试、生产环境最佳实践以及微服务架构中的集成方案,帮助开发者掌握OAuth2.0的核心技术。

weixin_27722377的博客 417

spring-security-oauth2(授权模式入门简单使用)

当前应用需要实现第三方登入,那么第三方是如何进行授权认证的?这就是oauth2协议。模拟实现微信端是如何进行授权认证登入。举例:豆瓣就是客户应用,授权服务器、资源服务器就是微信端持有。豆瓣需要向微信的授权服务器获取授权,获取到授权后再向资源服务器获取用户信息。那么我们就需要1.需要配置一个授权服务器(发放授权码)2.配置一个资源服务器(获取用户信息接口需要令牌才能访问)3.配置一个接口(获取返回用户信息)4.还要实现模拟用户的登入(因为授权服务器需要向用户发起是否允许授权的请求)......

IABQL的博客 3255

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例

在前几篇文档中,我们学习了OAuth 2.0协议,并使用完成了基于授权码模式的第三方平台登录功能。OAuth 2.0中的四大角色,原生框架已经帮我们实现了资源所有者、客户端、资源服务器,那么Spring是否提供了授权服务器的实现呢?在OAuth 1.0时代,Spring组织已经开始开发基于对OAuth的支持,该框架就是。其实现了大部分的OAuth规范,并提供了资源服务器、客户端和授权服务器。

记录知识、锤炼自我 8366

Spring Security OAuth2 配置详解

Spring Security 是一个强大且灵活的框架,用于保护基于 Java 的应用程序的安全性。在本文中,我们将详细介绍如何配置 Spring Security OAuth2,并提供相应的源代码示例。这是一个简单的示例,展示了如何配置 Spring Security OAuth2。但是,通过上述配置,你应该能够开始构建安全性强大的基于 OAuth2 的应用程序。我们配置了一个内存中的客户端,并指定了授权类型、范围和重定向 URL。我们配置了一个简单的规则,要求所有请求都必须经过身份验证。

DevSavantX的博客 481

Spring Security- 授权码模式的实战配置与实现

🌿 Spring Security - 授权码模式的实战配置与实现 摘要 本文详细介绍了如何使用Spring Security实现OAuth2授权码模式,这是OAuth2中最安全且常用的授权方式。文章从OAuth2基本概念讲起,重点分析了授权码模式的工作流程和优势,包括其安全性特点(令牌在后端传输、支持刷新令牌等)。通过清晰的架构图示和代码示例,展示了如何搭建包含授权服务器和资源服务器的完整认证系统。技术实现方面,基于Spring Boot 3.x和Spring Security 6+,详细说明了项目初始

千淘万漉虽辛苦,吹尽狂沙始到金 1万+

如何读懂CiteSpace图谱?科研小白必看的节点颜色/年轮/聚类解读手册

本文详细解析CiteSpace图谱的核心视觉元素,包括节点颜色、年轮和聚类标识,帮助科研人员准确解读数据分析结果。通过生物医学案例展示如何从图谱中识别关键文献和研究趋势,提供五步系统解读法和常见错误规避策略,助力科研小白快速掌握文献计量分析技巧。

weixin_29179311的博客 316

Spring Security OAuth2与JWT集成最佳实践

本文深入探讨Spring Security OAuth2与JWT(JSON Web Token)的集成实现,通过分析auth项目的实际代码,详细讲解OAuth2协议与JWT令牌的结合使用、安全配置、令牌管理、性能优化等关键技术点。文章涵盖JWT令牌生成与验证、OAuth2端点配置、安全策略实现等内容,为开发者提供完整的集成解决方案。"""令牌增强器接口""""""增强令牌信息"""pass"""自定义令牌增强器""""""增强令牌,添加自定义信息"""# 添加自定义声明。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 1067

Cadence DSP 算子开发实战:从入门到精通

本文详细介绍了Cadence DSP算子开发的实战技巧,从入门基础到高级优化。内容涵盖DSP架构特性、内存管理、分块计算策略、SIMD指令优化等核心知识,并提供了性能调优和调试的实用技巧,帮助开发者快速掌握Cadence DSP开发精髓,提升图像处理等计算密集型任务的开发效率。

weixin_29278805的博客 435

OneOS远程升级能力实操演示 | OTA升级

OneOS远程升级能力实操演示,差分算法提升效率,OTA升级,OTA差分算法,全量升级、压缩升级、差分升级,有线网络连接,bootloader,升级平台,在线差分包制作,触摸屏以及GUI图形操作

OneOS是中国移动针对物联网领域推出的轻量级操作系统 2011

授权码模式核心机制全解析,彻底搞懂Spring Security OAuth2身份验证链

深入解析Spring Security OAuth2 授权码模式,掌握安全高效的认证流程设计。涵盖OAuth2核心原理、授权码模式适用场景及关键配置步骤,提升系统安全性与可扩展性,值得收藏。

FastDebug的博客 535

Aruba CX交换机VSX配置实战:如何避免脑裂导致的网络中断(含详细命令)

本文提供Aruba CX交换机VSX配置的实战指南,重点讲解如何通过构建高可靠的ISL链路聚合与独立隔离的Keepalive链路,有效避免网络脑裂风险。文章包含详细的命令步骤,从基础配置到高级故障排查,帮助网络工程师构建坚如磐石的高可用核心网络,确保业务流量零中断。

weixin_29231725的博客 172

spring-rest-service-oauth高级特性:如何扩展授权服务器与资源服务器

spring-rest-service-oauth是一个基于Spring Boot和Spring Security OAuth构建的简单OAuth保护REST服务,本文将详细介绍如何扩展其授权服务器与资源服务器,帮助开发者轻松实现更灵活的认证授权功能。 ## 授权服务器的核心配置与扩展 授权服务器是OAuth2认证流程的核心组件,负责颁发访问令牌和刷新令牌。在spring-rest-servi

gitblog_00593的博客 782

第1集:认识 Claude Code —— AI 编程新纪元

1. 定义 Claude Code:终端中的 AI 编程代理Claude Code 是 Anthropic 公司于 2025 年 5 月正式推出的命令行 AI 编程工具,它不只是一个代码补全工具,而是一个能够理解项目、自主执行任务的**终端 AI 代理(Agent)。它的核心理念是 **"生于终端,活于终端"** (lives in your terminal)。与深度嵌入图形界面(GUI)的工具不同,Claude Code 选择直接融入开发者最原始、最核心的工作环境——命令行。

dianziyao_的博客 865

SAP SEGW 事物码里的 Function Import

开放数据协议(OData)包括标准的 CRUD (创建、检索、更新和删除)操作,这些操作映射到 HTTP 方法的 POST、GET、PUT/MERGE 和 Delete 几类。此外,OData还支持进一步的服务操作:,这些操作可以由HTTP方法GET或POST调用,用于处理不能映射到标准 CRUD 操作的任何内容。通过在数据模型中创建 ,可以在 service Builder 中实现此类额外的服务操作。例如,您可以为以下自定义操作创建函数导入:Work Item confirmation检查航班的可用性虽然

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 995

Springboot 3 + Spring Security 6 + OAuth2 入门级最佳实践

您可以采用 JPA/Hibernate等一切你所熟悉的数据库框架,但这并不是本文档的重点。这里仅以MySQL 8.x与MybatisPlus为例:我们这里没有实现注册模块,但又想体验密码加密功能,因此推荐从此处由纯文本密码转换成加密密码存储至数据库中。编写授权服务// }创建两个实体类其一:User// 导入 Lombok 库中的注解import lombok.Builder;

竹林幽深 2036

人形机器人构成及成本估算(附报告)

这些执行器本身由螺杆、减速器、电机、传感器、滚珠轴承和编码器等组件构成。实现线性与旋转运动互转。人形机器人的运动系统可以由电驱动、液压驱动或气动驱动组成,但由于电驱动具有更高的精度和更快的响应速度,正在成为主流设计方案。执行器:NSK、THK、Harmonic Drive、Leaderdrive、Nidec、Moons。由螺杆、减速器、电机、传感器、轴承和编码器组成(如上为Tesla Optimus执行器设计示意)。传感器:Keyence、Robosense、Sensata、ATI、TE、Sony。

具身机器人和通用AI 1775

Spring Security OAuth2实战:构建基于JWT的微服务认证授权中心

在分布式系统与微服务架构中,认证与授权是保障应用安全的核心基础设施。OAuth2作为行业标准的授权框架,通过定义客户端、资源所有者、授权服务器和资源服务器之间的交互协议,实现了安全的第三方应用访问授权。其核心原理在于使用访问令牌替代用户凭证,有效分离了认证与授权职责,提升了系统的安全性与可扩展性。JWT(JSON Web Token)作为一种紧凑的、自包含的令牌格式,因其无状态、易于传输和解析的特性,成为实现OAuth2令牌的理想选择,尤其适用于微服务间的通信。通过将用户声明信息编码进令牌本身,资源服务器无

weixin_33906657的博客 308

RSL-RL:开源人形机器人强化学习控制研究库

摘要:RSL-RL是一款专为机器人领域设计的开源强化学习库,其核心特点是紧凑性、可修改性和高性能。该库聚焦PPO和BC两大主流算法,并整合了对称性增强、好奇心驱动等机器人专用技术。通过纯GPU训练优化,RSL-RL在大型仿真中展现出卓越的吞吐性能,已成功应用于腿足运动控制、全身协调等多个机器人研究场景。其轻量级架构包含运行器、算法和网络三个可独立修改的组件,支持TensorBoard等主流日志工具。该框架特别适合需要快速原型开发的机器人研究者,但不适用于通用机器学习基准测试。开源地址:https://git

2506_90492529的博客 1675

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

OAuth2.0授权码模式零基础实战

*** 用户信息查询服务* 真实项目替换Mybatis/MybatisPlus数据库查询*/@Service/**根据用户名查询用户*/@Override// 模拟数据库用户:账号admin,原始密码123456if (!throw new UsernameNotFoundException("登录用户不存在");username,// 用户权限集合。

只要肯攀登,终有登顶时 368

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

spring boot + spring security+ oauth2鉴权双系统开发记录

 以前项目在授权的时候,都是使用的自定义的授权令牌token,具体的实现思路是在登录的时候生成一个随机的token,设置超时时间后放入redis缓存中,前端每次访问需要鉴权的资源的时候都需要附带上token令牌,后端写一个切面对访问路径进行验证,如果需要鉴权的就进行token令牌对比,通过后刷新令牌的超时时间,当前端token失效了,则返回给前端失效结果让前端重新登录。  后来又使用过shiro...

qq904748592的博客 3928

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Spring Security安全框架:认证授权与OAuth2集成

Spring Security作为Spring生态系统的核心安全框架,提供了完整的认证、授权和安全防护机制。本文深入解析Spring Security的过滤器链架构、基于角色的访问控制(RBAC)实现、OAuth2.0授权服务器与资源服务器配置,以及JWT令牌在微服务环境中的最佳实践。通过详细的代码示例和架构图,展示如何构建安全可靠的现代应用程序,涵盖从基础认证到高级OAuth2集成的全方位安全解...

gitblog_01072的博客 313
上一篇: Java多线程开发中的Springboot 中异步请求方法的使用
下一篇: 华为十年大佬带你开启springboot实战之旅,从源码到项目,一步到位!
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值