我在参考文章2的基础上实现了oauth2的客户端和密码模式,存储在内存中,进一步的,我想通过参考文章2实现从数据库中读取配置文件。
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"));
|
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
|