# SSO单点登录-Oauth2.1 **Repository Path**: lslands/yang-oauth2 ## Basic Information - **Project Name**: SSO单点登录-Oauth2.1 - **Description**: SpringSecurity3.x+Oauth2.1+JWT - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-05-11 - **Last Updated**: 2024-06-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SSO单点登录-Oauth2.1 ## v1.0.2 > **##目标** > 原有的客户端注册中心是基于内存的InMemoryRegisteredClientRepository,需要改造为基于数据库,可动态注册即修改客户端信息 > 用户信息UserDetailsService也是基于内存,现在需要基于数据库动态添加编辑 > 各种异常的自定义处理与信息返回 > 用户信息的自定义返回 > 过期时间、授权方式 > 新增客户端client,从客户端作为入口并配置相关组件 SQL脚本 ```mysql 2.1 oauth2_authorization 令牌发放记录表 -- ---------------------------- CREATE TABLE oauth2_authorization ( id varchar(100) NOT NULL COMMENT '令牌ID', registered_client_id varchar(100) NOT NULL COMMENT '注册的客户端ID', principal_name varchar(200) NOT NULL COMMENT '主体名称', authorization_grant_type varchar(100) NOT NULL COMMENT '授权授予类型', authorized_scopes varchar(1000) DEFAULT NULL COMMENT '授权范围', attributes blob DEFAULT NULL COMMENT '属性', state varchar(500) DEFAULT NULL COMMENT '状态', authorization_code_value blob DEFAULT NULL COMMENT '授权码值', authorization_code_issued_at timestamp DEFAULT NULL COMMENT '授权码颁发时间', authorization_code_expires_at timestamp DEFAULT NULL COMMENT '授权码过期时间', authorization_code_metadata blob DEFAULT NULL COMMENT '授权码元数据', access_token_value blob DEFAULT NULL COMMENT '访问令牌值', access_token_issued_at timestamp DEFAULT NULL COMMENT '访问令牌颁发时间', access_token_expires_at timestamp DEFAULT NULL COMMENT '访问令牌过期时间', access_token_metadata blob DEFAULT NULL COMMENT '访问令牌元数据', access_token_type varchar(100) DEFAULT NULL COMMENT '访问令牌类型', access_token_scopes varchar(1000) DEFAULT NULL COMMENT '访问令牌范围', oidc_id_token_value blob DEFAULT NULL COMMENT 'OIDC ID 令牌值', oidc_id_token_issued_at timestamp DEFAULT NULL COMMENT 'OIDC ID 令牌颁发时间', oidc_id_token_expires_at timestamp DEFAULT NULL COMMENT 'OIDC ID 令牌过期时间', oidc_id_token_metadata blob DEFAULT NULL COMMENT 'OIDC ID 令牌元数据', refresh_token_value blob DEFAULT NULL COMMENT '刷新令牌值', refresh_token_issued_at timestamp DEFAULT NULL COMMENT '刷新令牌颁发时间', refresh_token_expires_at timestamp DEFAULT NULL COMMENT '刷新令牌过期时间', refresh_token_metadata blob DEFAULT NULL COMMENT '刷新令牌元数据', user_code_value blob DEFAULT NULL COMMENT '用户代码值', user_code_issued_at timestamp DEFAULT NULL COMMENT '用户代码颁发时间', user_code_expires_at timestamp DEFAULT NULL COMMENT '用户代码过期时间', user_code_metadata blob DEFAULT NULL COMMENT '用户代码元数据', device_code_value blob DEFAULT NULL COMMENT '设备代码值', device_code_issued_at timestamp DEFAULT NULL COMMENT '设备代码颁发时间', device_code_expires_at timestamp DEFAULT NULL COMMENT '设备代码过期时间', device_code_metadata blob DEFAULT NULL COMMENT '设备代码元数据', PRIMARY KEY (id) ); -- ---------------------------- -- 2.2 oauth2_authorization_consent 授权记录表 -- ---------------------------- CREATE TABLE oauth2_authorization_consent ( registered_client_id varchar(100) NOT NULL COMMENT '注册的客户端ID', principal_name varchar(200) NOT NULL COMMENT '主体名称', authorities varchar(1000) NOT NULL COMMENT '授权', PRIMARY KEY (registered_client_id, principal_name) ); -- ---------------------------- -- 2.3 oauth2-registered-client OAuth2 客户端信息表 -- ---------------------------- CREATE TABLE oauth2_registered_client ( id varchar(100) NOT NULL COMMENT '客户端ID', client_id varchar(100) NOT NULL COMMENT '客户端ID', client_id_issued_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '客户端ID颁发时间', client_secret varchar(200) DEFAULT NULL COMMENT '客户端密钥', client_secret_expires_at timestamp DEFAULT NULL COMMENT '客户端密钥过期时间', client_name varchar(200) NOT NULL COMMENT '客户端名称', client_authentication_methods varchar(1000) NOT NULL COMMENT '客户端认证方法', authorization_grant_types varchar(1000) NOT NULL COMMENT '授权授予类型', redirect_uris varchar(1000) DEFAULT NULL COMMENT '重定向URI', post_logout_redirect_uris varchar(1000) DEFAULT NULL COMMENT '注销后重定向URI', scopes varchar(1000) NOT NULL COMMENT '授权范围', client_settings varchar(2000) NOT NULL COMMENT '客户端设置', token_settings varchar(2000) NOT NULL COMMENT '令牌设置', PRIMARY KEY (id) ); ``` ## v1.0.1 ### 项目详解 ===重要组件=== - SecurityFilterChain -> authorizationServerSecurityFilterChain: Spring Security的过滤器链,用于协议端点的。 - SecurityFilterChain -> defaultSecurityFilterChain: Spring Security的过滤器链,用于Spring Security的身份认证 - UserDetailsService :主要进行用户身份验证 - RegisteredClientRepository:主要用于管理客户端 - JWKSource:用于签名访问令牌 - KeyPair: 启动时生成的带有密钥的KeyPair实例,用于创建上面的JWKSource - JwtDecoder:JwtDecoder的一个实例,用于解码已签名的访问令牌 - AuthorizationServerSettings:用于配置Spring Authorization Server的AuthorizationServerSettings实例。 ### 项目测试 #### 1.查看授权服务配置 **请求地址**: > http://127.0.0.1:9110/.well-known/openid-configuration **请求结果**: ![image-20240512130341953](/Users/lslands/Desktop/2023/spring-cloud/doc/文档图片/image-20240512130341953-5490232.png) #### 2.访问授权服务器 **请求地址**: > http://127.0.01:9110/oauth2/authorize?response_type=code&client_id=yang&scope=all&redirect_uri=http://www.baidu.com 用这个请求来模拟客户端,实际开发中,其实是先访问资源服务,由资源服务来拼接这几个参数来重定向到授权服务的,参数意义如下,***\*这些参数都是需要再上面RegisteredClientRepository配置过的\**** > - response_type:这个意思是相应的方式为code码 > - client_id:即客户端的id,即上面配置中在 RegisteredClientRepository 配置的 > - scope:请求授权范围,也需要在上面的配置中 > - redirect_uri:授权通过后,重定向回来的地址 **请求结果** 授权 ![image-20240512130811509](/Users/lslands/Desktop/2023/spring-cloud/doc/文档图片/image-20240512130811509.png) 回调 ![image-20240512143843514](/Users/lslands/Desktop/2023/spring-cloud/doc/文档图片/image-20240512143843514.png) #### 3.获取access_token 当通过第 2 获取到授权码后,请求授权服务器获取token > http://127.0.01:9110/oauth2/token?grant_type=authorization_code&code="授权码" > > ##参数说明 > > grant_type:即授权方式,authorization_code即授权码模式 > code:即授权码,上面重定向到百度给我们的授权码 > redirect_uri:重定向的url > header中的 Authorization参数:因为我们用的客户端认证方式 为 client_secret_basic ,这个需要传参,还有一些其他的认证方式,具体参数说明如下 > > client_secret_basic: 将 clientId 和 clientSecret 通过 ‘:’ 号拼接,( clientId 和 clientSecret 都在上面配置中,)并使用 Base64 进行编码得到一串字符,再在前面加个 注意有个 Basic 前缀(Basic后有一个空格), 即得到上面参数中的 Basic b2lkYy1jbGllbnQ6c2VjcmV0 > > **请求示例** ![image-20240512144421766](/Users/lslands/Desktop/2023/spring-cloud/doc/文档图片/image-20240512144421766.png) ![image-20240512144259634](/Users/lslands/Desktop/2023/spring-cloud/doc/文档图片/image-20240512144259634.png) #### 4.获取用户信息 获取用户信息接口为 /userinfo,注意需要有 opid 的授权范围,需要传参的值为 上面获取到的access_token,并在前面拼上 Bearer 。 **请求地址** > http:127.0.0.1:9110/userinfo 参数说明 > Authorization:值格式为 Bearer + ${access_token}, 注意 Bearer 后面附带空格