3 Star 10 Fork 36

罗小爬 / oauth2-auth-server-oidc

forked from 罗小爬 / spring-cloud-demo 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 14.00 KB
一键复制 编辑 原始数据 按行查看 历史
luo.hq 提交于 2022-03-18 12:39 . 调整验证码默认字体设置

Spring Authorization Server - OIDC扩展

模块说明:

模块 说明
oauth2-auth-server-oidc-base OIDC AuthServer核心功能Base模块,其他示例模块均依赖此模块
samples/oauth2-auth-server-oidc-minimal OIDC AuthServer最小集成示例
samples/oauth2-auth-server-oidc-token-ext OIDC AuthServer扩展token示例
samples/oauth2-auth-server-oidc-resource OIDC AuthServer同时作为Resource Server示例
samples/oauth2-auth-server-oidc-login-captcha OIDC AuthServer自定义登录图片验证码集成示例
samples/oauth2-auth-server-oidc-login-third OIDC AuthServer集成第三方OAuth2(GitHub)登录示例
samples/oauth2-auth-server-oidc-session OIDC AuthServer共享session集成示例(支持AuthServer分布式部署)
samples/oauth2-auth-server-oidc-combo OIDC AuthServer综合集成示例(自定义登录页、手机验证码登录、token扩展、第三方登录、同时作为资源服务器)
samples/oauth2-client1 Spring Security OAuth2 Client示例1(使用Authorization Code + PKCE)
samples/oauth2-client2 Spring Security OAuth2 Client示例2(使用Authorization Code)
samples/oauth2-resource-server-jwt Spring Security OAuth2 Resource Server示例1(使用Jwt验证)
samples/oauth2-resource-server-jwt Spring Security OAuth2 Resource Server示例2(使用OpaqueToken验证,即使用introspection_endpoint)
samples/sample-common samples通用基础模块(仅提取示例中的通用部分,无实际作用)

oauth2-auth-server-oidc-base扩展点

默认账号密码:root/123456

RP注册信息配置

@Resource
private JdbcRegisteredClientRepository registeredClientRepository;
    
@Test
void regOidcClient() {
    RegisteredClient registeredClient_client1 = RegisteredClient.withId(UUID.randomUUID().toString())
                    //客户端名称
                    .clientName("luo-oauth2-client1 - 客户端")
                    //客户端ID和Secret(需在Client端进行配置),且Secret需使用对应的PasswordEncoder进行编码
                    .clientId("luo-oauth2-client1")
                    .clientSecret("{bcrypt}$2a$10$LgGXHSU2Fh/dCLIwrOetiOnCK3Zypeo588EpAOQeJAnT0kdiia6em")
                    //客户端认证方法
                    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
                    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                    //客户端认证方none - 若开启PKCE认证,则需添加none认证方法,否则
                    .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
                    //支持的OAuth2授权模式(authorization_code和refresh_token)
                    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                    .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                    //在OP端认证成功后的回调(重定向回RP端)URI
                    .redirectUri("http://oauth2-client1:8081/login/oauth2/code/luo-oauth2-client1")
                    //添加Client端对应的权限scope
                    .scope(OidcScopes.OPENID)
                    .scope(OidcScopes.PHONE)
                    .scope(OidcScopes.EMAIL)
                    .scope(OidcScopes.PROFILE)
                    //支持PKCE模式下(无client_secret)获取refresh_token
                    .scope(OIDCScopeValue.OFFLINE_ACCESS.getValue())
                    .scope("articles.read")
                    .scope("roles")
                    //Client相关设置
                    .clientSettings(ClientSettings.builder()
                            //是否需要展示权限确认页面
                            .requireAuthorizationConsent(true)
                            //是否需要开启PKCE模式(SPA建议开启)
                            .requireProofKey(true)
    
                            //如下两项jwtSetUrl、tokenEndpointAuthenticationSigningAlgorithm适用于认证方法private_key_jwt和client_secret_jwt,
                            //以上使用的client_secret_post和client_secret_basic可不用配置
                            //覆盖Client端的jwksSetUrl
                            //.jwkSetUrl(null)
                            //设置client认证(private_key_jwt和client_secret_jwt)JWT签名算法
                            //.tokenEndpointAuthenticationSigningAlgorithm(SignatureAlgorithm.RS256)
    
                            //注:idToken、accessToke均使用RS256签名算法,目前不可配置,参见:JwtUtils.headers方法
                            //自定义配置(如自定义OIDC协议中RP的前端、后端登出URI)
                            .setting(CLIENT_SETTINGS.FRONTCHANNEL_LOGOUT_URI, "http://oauth2-client1:8081/front_logout")
                            .setting(CLIENT_SETTINGS.BACKCHANNEL_LOGOUT_URI, "http://oauth2-client1:8081/back_logout")
                            .build())
                    //Token相关设置
                    .tokenSettings(TokenSettings.builder()
                            //accessToken生存时长(即超过多久失效,默认5分钟)
                            .accessTokenTimeToLive(Duration.ofMinutes(5))
                            //refreshToken生存时长(即超过多久失效,默认60分钟)
                            .refreshTokenTimeToLive(Duration.ofMinutes(60))
                            //执行刷新token流程时,是否返回新的refreshToken(默认true即重用refreshToken),
                            //true则重用之前的refreshToken,false则生成新的refreshToken及生存时长
                            .reuseRefreshTokens(false)
                            //设置idToken签名算法 TODO 参见 OidcClientRegistrationEndpointFilter 逻辑
                            .idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
                            //支持PKCE模式下(无client_secret)执行refresh_token流程
                            .setting(TOKEN_SETTINGS.ALLOW_PUBLIC_CLIENT_REFRESH_TOKEN, true)
                            //注:idToken默认生存时长30分钟,目前不可配置,参见:JwtUtils.idTokenClaims方法
                            //注:code有效时长5分钟,目前不可配置,参见:OAuth2AuthorizationCodeRequestAuthenticationProvider.generateAuthorizationCode
                            //注:session时长 > refreshToken刷新时长
                            //TODO 注:session时长  remember-me时长
                            .build())

    registeredClientRepository.save(registeredClient_client1);
}

示例工程说明

本地运行示例模块Host配置:

127.0.0.1 oauth2-server

127.0.0.1 oauth2-client1

127.0.0.1 oauth2-client2

127.0.0.1 oauth2-resource1

127.0.0.1 oauth2-resource2

示例oauth2-client1和oauth2-client2的客户端注册信息如下:

INSERT INTO oauth2_registered_client (
	id, 
	client_id, 
	client_id_issued_at, 
	client_secret, 
	client_secret_expires_at, 
	client_name,
	client_authentication_methods, 
	authorization_grant_types, 
	redirect_uris, 
	scopes, 
	client_settings, 
	token_settings 
)
VALUES
(
	'b8756f02-af55-4b39-a173-22bbfda82d9f', 
	'luo-oauth2-client1', 
	'2022-03-07 09:10:03', 
	'{bcrypt}$2a$10$LgGXHSU2Fh/dCLIwrOetiOnCK3Zypeo588EpAOQeJAnT0kdiia6em', 
	NULL, 
	'luo-oauth2-client1 - 客户端', 
	'client_secret_post,client_secret_basic,none', 
	'refresh_token,authorization_code,password', 
	'http://oauth2-client1:8081/login/oauth2/code/luo-oauth2-client1', 
	'articles.read,phone,openid,profile,roles,email,offline_access', 
	'{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-authorization-consent\":true,\"settings.client.require-proof-key\":true,\"frontchannel_logout_uri\":\"http://oauth2-client1:8081/front_logout\"}', '{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.token.reuse-refresh-tokens\":false,\"settings.token.allow-public-client-refresh-token\":true,\"settings.token.id-token-signature-algorithm\":[\"org.springframework.security.oauth2.jose.jws.SignatureAlgorithm\",\"RS256\"],\"settings.token.access-token-time-to-live\":[\"java.time.Duration\",300.000000000],\"settings.token.refresh-token-time-to-live\":[\"java.time.Duration\",3600.000000000]}'
),
( 
	'8b767dc8-de43-4705-8b10-72ef642cfbbc', 
	'luo-oauth2-client2', 
	'2022-03-07 09:10:04', 
	'{bcrypt}$2a$10$xw.pBLQitbNdAAyBhuBAo.IIP8dbDHcXF5c1YNIDqhhcC18cmNGo2', 
	NULL, 
	'luo-oauth2-client2 - 客户端', 
	'client_secret_post,client_secret_basic,none', 
	'refresh_token,authorization_code', 
	'http://oauth2-client2:8082/login/oauth2/code/luo-oauth2-client2', 
	'articles.read,phone,openid,profile,roles,email', 
	'{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-authorization-consent\":true,\"settings.client.require-proof-key\":false,\"frontchannel_logout_uri\":\"http://oauth2-client2:8082/front_logout\"}', '{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.token.reuse-refresh-tokens\":true,\"settings.token.id-token-signature-algorithm\":[\"org.springframework.security.oauth2.jose.jws.SignatureAlgorithm\",\"RS256\"],\"settings.token.access-token-time-to-live\":[\"java.time.Duration\",300.000000000],\"settings.token.refresh-token-time-to-live\":[\"java.time.Duration\",3600.000000000]}' 
);

OIDC AuthServer最小接入 - 用户名、密码登录(默认root/123456)

参见示例:oauth2-auth-server-oidc-minimal

  1. 新建对应Mysql库oauth2-server(名称可适当调整)并导入oauth2-auth-server-oidc-base/src/main/resources/sql/oidc-authorization-server.sql
  2. 根据需要配置具体client注册信息(可参见测试用例)
  3. 可通过自定义UserDetailsService实现来根据用户名检索用户及密码信息
  4. 配置OIDC Authorization相关属性(需生成RSA对称密钥对)

OIDC AuthServer同时作为Resource Server

参见示例:oauth2-auth-server-oidc-resource

OIDC AuthServer扩展token

扩展token需实现:DefaultOidcTokenCustomer.AbstractOidcTokenCustomerExtend

扩展userinfo需实现:DefaultOidcUserInfoMapper.OidcUserInfoMapperExtend

  • accessToken
  • refreshToken
  • idToken
  • userInfo

参见示例:oauth2-auth-server-oidc-token-ext

OIDC AuthServer自定义登录 - 图片验证码

参见示例:oauth2-auth-server-oidc-login-captcha

OIDC AuthServer自定义登录 - 集成第三方登录(GitHub)

参见示例:oauth2-auth-server-oidc-login-third

OIDC AuthServer自定义登录 - 组合集成

  • 自定义登录页
  • 手机验证码登录
  • token扩展
  • 第三方登录
  • 同时作为资源服务器

参见示例:oauth2-auth-server-oidc-login-third

OIDC AuthServer集成共享Session

参见示例:oauth2-auth-server-oidc-login-session

1
https://gitee.com/luoex/oauth2-auth-server-oidc.git
git@gitee.com:luoex/oauth2-auth-server-oidc.git
luoex
oauth2-auth-server-oidc
oauth2-auth-server-oidc
main

搜索帮助