我在参考文章2的基础上实现了oauth2的客户端和密码模式,存储在内存中,进一步的,我想通过参考文章2实现从数据库中读取配置文件。
参考文章:
1.微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权! (这篇文章实现了oauth2的密码模式和客户端模式)
2.oauth2.0通过JdbcClientDetailsService从数据库读取相应的配置 (这篇文章是我的主要参考文章,实现JdbcClientDetalsService,也是我的第一篇参考文章,但是他的需求和我的稍微一些不一样,就是我实现的是client模式,而不是授权码模式)
3.Springboot2+SpringSecurity+Oauth2+Mysql数据库实现持久化客户端数据 (这篇文章里面的代码有点乱,没有换行)
4.Spring Security +Oauth2 +Spring boot 动态定义权限 (这篇文章暂时没有用到)
1.数据表
提供的参考文章是使用的MySQL数据库,我这里改成了SQL Server数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| CREATE TABLE [数据库名].dbo.oauth_client_details ( client_id varchar(48) NOT NULL, resource_ids varchar(256) DEFAULT NULL, client_secret varchar(256) DEFAULT NULL, scope varchar(256) DEFAULT NULL, authorized_grant_types varchar(256) DEFAULT NULL, web_server_redirect_uri varchar(256) DEFAULT NULL, authorities varchar(256) DEFAULT NULL, access_token_validity int DEFAULT NULL, refresh_token_validity int DEFAULT NULL, additional_information varchar(4096) DEFAULT NULL, autoapprove varchar(256) DEFAULT NULL, PRIMARY KEY (client_id) )
|
数据例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { "oauth_client_details": [ { "client_id" : "client_2", "resource_ids" : null, "client_secret" : "$2a$10$Cjeag\/\/umnkFDVRNZlreP.RUCheKinx.2cX6IxnzdzIWYLfBMDy\/q", "scope" : "all", "authorized_grant_types" : "client_credentials", "web_server_redirect_uri" : null, "authorities" : "client", "access_token_validity" : null, "refresh_token_validity" : null, "additional_information" : null, "autoapprove" : null } ]}
|
其中的client_secret最好用bcrypt密文的方式进行存储,比如我下面的client_secret,明文是123456。可以使用PasswordEncoder类的encode方法产生相应的密码。
1 2
| private final PasswordEncoder passwordEncoder; System.out.println(passwordEncoder.encode("123456"));
|
参考文章:
1.SQL Server CREATE TABLE
2.该如何设计你的 PasswordEncoder? (密码的生成规则,以及密码的生成历史,多种密码策略以及相应的从明文到密文的过度方法)
2.pom.xml配置
因为用到了sql server数据库,然后还使用了jpa,于是添加下面的依赖。
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>8.1.0.jre8-preview</version> </dependency>
|
3.application.yml配置
在spring配置默认的数据源。
1 2 3 4 5 6 7 8 9 10
| spring: datasource: hikari: connection-timeout: 20000 maximum-pool-size: 5 username: xxx password: xx url: jdbc:sqlserver://xxx:5433;databasename=xxx driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
4.编写oauth2配置
这里我贴出了全部的Oauth2ServerConfig配置代码,其中大部分的内容也都是(微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权! (这篇文章实现了oauth2的密码模式和客户端模式))这篇文章中的,我只是改掉了ClientDetailsServiceConfigurer从数据库中获取配置的内容。除此之外,文章中还有些Token增强的内容,即在返回的内容之外又新添了自己的内容。
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| @AllArgsConstructor @Configuration @EnableAuthorizationServer public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {
private static final String RESOURCE_IDS = "order";
private final PasswordEncoder passwordEncoder; private final UserServiceImpl userDetailsService; private final AuthenticationManager authenticationManager; private final JwtTokenEnhancer jwtTokenEnhancer;
@Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientDetails()); }
@Resource private DataSource dataSource;
@Bean public ClientDetailsService clientDetails() { JdbcClientDetailsService jdbcClientDetailsService=new JdbcClientDetailsService(dataSource); jdbcClientDetailsService.setPasswordEncoder(); return jdbcClientDetailsService; }
@Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); List<TokenEnhancer> delegates = new ArrayList<>(); delegates.add(jwtTokenEnhancer); delegates.add(accessTokenConverter()); enhancerChain.setTokenEnhancers(delegates); endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService) .accessTokenConverter(accessTokenConverter()) .tokenEnhancer(enhancerChain); }
@Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.allowFormAuthenticationForClients(); }
@Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setKeyPair(keyPair()); return jwtAccessTokenConverter; }
@Bean public KeyPair keyPair() { KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray()); return keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray()); }
}
|
还有一点要说明的,就是生成密钥对的工具,在自己的java安装目录下的bin文件夹中。
使用下面的命令行即可生成。
1
| keytool -genkey -alias jwt -keyalg RSA -keystore jwt.jks
|
参考文章:
1.从头开始spring security oauth 2.0 (二)keytool (这篇文章中,还有一步”从生成的JKS中导出公钥”,我觉得没有必要,因为我用的示例代码只需要生成密钥然后拷贝到resource文件夹就好了)
2.pring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证
3.windows下使用keytool生成ssl自生成证书并在tomcat7中配置 (如何在windows上生成密钥)
4.Spring Security 实战干货:用户信息UserDetails相关入门 (放在这里没有什么用,就是看到了相关的信息,主要讲UserDetails的内容)
5.Spring Security入门(三):密码加密 (内容其实也不是很多,但是还是讲了Security默认的BCryptPasswordEncoder加密方式)
6.Spring Boot+OAuth2,如何自定义返回的 Token 信息?
7.想让 OAuth2 和 JWT 在一起愉快玩耍?请看松哥的表演