Spring OAuth2 授权服务器配置介绍
发布时间:2022-06-21 13:33:50 所属栏目:系统 来源:互联网
导读:前两篇文章分别体验了Spring Authorization Server的使用和讲解了其各个过滤器的作用。今天来讲讲Spring Authorization Server授权服务器的配置。强烈建议自己手动搭建一次试试,纸上得来终觉浅,深知此事要躬行。提升你的代码量才是提高编程技能的不二法门
前两篇文章分别体验了Spring Authorization Server的使用和讲解了其各个过滤器的作用。今天来讲讲Spring Authorization Server授权服务器的配置。强烈建议自己手动搭建一次试试,纸上得来终觉浅,深知此事要躬行。提升你的代码量才是提高编程技能的不二法门,这也是本篇教程的意义所在。 配置依赖 首先要创建一个Spring Boot Servlet Web项目,这个不难就不赘述了。集成Spring Authorization Server需要引入: 复制 <!-- spring security starter 必须 --> <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.2.0</version> </dependency> 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. OAuth2.0 Client客户端需要注册到授权服务器并持久化,Spring Authorization Server提供了JDBC实现,参见JdbcRegisteredClientRepository。为了演示方便这里我采用了H2数据库,需要以下依赖: 复制 <!-- jdbc 必须引入否则自行实现 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> 1. 2. 3. 4. 5. 6. 7. 8. 9. 生产你可以切换到其它关系型数据库,数据库脚本在Spring Authorization Server入门 一文的DEMO中。 Spring Authorization Server配置 接下来是Spring Authorization Server的配置。 过滤器链配置 根据上一文对过滤器链的拆解,我们需要在Spring Security的过滤器链中注入一些特定的过滤器。这些过滤器的配置由OAuth2AuthorizationServerConfigurer来完成。以下为默认的配置: 复制 void defaultOAuth2AuthorizationServerConfigurer(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer<>(); // TODO 你可以根据需求对authorizationServerConfigurer进行一些个性化配置 RequestMatcher authorizationServerEndpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); // 拦截 授权服务器相关的请求端点 http.requestMatcher(authorizationServerEndpointsMatcher) .authorizeRequests().anyRequest().authenticated().and() // 忽略掉相关端点的csrf .csrf(csrf -> csrf.ignoringRequestMatchers(authorizationServerEndpointsMatcher)) // 开启form登录 .formLogin() .and() // 应用 授权服务器的配置 .apply(authorizationServerConfigurer); } 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 你可以调用OAuth2AuthorizationServerConfigurer提供的配置方法进行一些个性化配置。 OAuth2.0客户端信息持久化 这些信息会持久化到数据库,Spring Authorization Server提供了三个DDL脚本。在入门教程的DEMO,H2会自动初始化执行这些DDL脚本,如果你切换到Mysql等数据库,可能需要你自行执行。 客户端配置信息注册 授权服务器要求客户端必须是已经注册的,避免非法的客户端发起授权申请。就像你平常去一些开放平台申请一个ClientID和Secret。下面是定义脚本: 复制 CREATE TABLE oauth2_registered_client ( id varchar(100) NOT NULL, client_id varchar(100) NOT NULL, client_id_issued_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, client_secret varchar(200) NULL, client_secret_expires_at timestamp NULL, client_name varchar(200) NOT NULL, client_authentication_methods varchar(1000) NOT NULL, authorization_grant_types varchar(1000) NOT NULL, redirect_uris varchar(1000) NULL, scopes varchar(1000) NOT NULL, client_settings varchar(2000) NOT NULL, token_settings varchar(2000) NOT NULL, PRIMARY KEY (id) ); 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 对应的Java类为RegisteredClient: 复制 public class RegisteredClient implements Serializable { private static final long serialVersionUID = Version.SERIAL_VERSION_UID; private String id; private String clientId; private Instant clientIdIssuedAt; private String clientSecret; private Instant clientSecretExpiresAt; private String clientName; private Set<ClientAuthenticationMethod> clientAuthenticationMethods; private Set<AuthorizationGrantType> authorizationGrantTypes; private Set<String> redirectUris; private Set<String> scopes; private ClientSettings clientSettings; private TokenSettings tokenSettings; // 省略 } 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 定义一个客户端可以通过下面的Builder方法实现: 复制 RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) // 唯一的客户端ID和密码 .clientId("felord-client") .clientSecret("secret") // 名称 可不定义 .clientName("felord") // 授权方法 .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) // 授权类型 .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) // 回调地址名单,不在此列将被拒绝 而且只能使用IP或者域名 不能使用 localhost .redirectUri("http://127.0.0.1:8080/login/oauth2/code/felord-oidc") .redirectUri("http://127.0.0.1:8080/authorized") .redirectUri("http://127.0.0.1:8080/foo/bar") .redirectUri("https://baidu.com") // OIDC支持 .scope(OidcScopes.OPENID) // 其它Scope .scope("message.read") .scope("message.write") // JWT的配置项 包括TTL 是否复用refreshToken等等 .tokenSettings(TokenSettings.builder().build()) // 配置客户端相关的配置项,包括验证密钥或者 是否需要授权页面 .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) .build(); 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 持久化到数据库的RegisteredClient用JSON表示为: 复制 { "id": "658cd010-4d8c-4824-a8c7-a86b642299af", "client_id": "felord-client", "client_id_issued_at": "2021-11-11 18:01:09", "client_secret": "{bcrypt}$2a$10$XKZ8iUckDcdQWnqw682zV.DVyGuov8Sywx1KyAn4tySsw.Jtltg0.", "client_secret_expires_at": null, "client_name": "felord", "client_authentication_methods": "client_secret_basic", "authorization_grant_types": "refresh_token,client_credentials,authorization_code", "redirect_uris": "http://127.0.0.1:8080/foo/bar,http://127.0.0.1:8080/authorized,http://127.0.0.1:8080/login/oauth2/code/felord-oidc,https://baidu.com", "scopes": "openid,message.read,message.write", "client_settings": "{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}", "token_settings": "{"@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]}" } 14. 注意上面的配置和你OAuth2.0客户端应用的配置息息相关。 既然持久化了,那自然需要操作该表的JDBC服务接口了,这个接口为RegisteredClientRepository。我们需要声明一个实现为Spring Bean,这里选择基于JDBC的实现: 复制 @Bean public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) { return new JdbcRegisteredClientRepository(jdbcTemplate); } 1. 2. 3. 4. 别忘记调用save(RegisteredClient)方法把需要注册的客户端信息持久化。 该实现依赖spring-boot-starter-jdbc类库,你也可以闲得慌使用Mybatis进行实现。 (编辑:开发网_开封站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐
热点阅读