当前位置:网站首页>Oauth2.0 - use database to store client information and authorization code
Oauth2.0 - use database to store client information and authorization code
2022-07-03 06:02:00 【Xiao bichao】
One 、OAuth2.0
In the last article, we introduced the use of JWT
Replace Token
Reduce the pressure of certification services , But to the client , And authorization code are stored in memory , Once the certification service goes down , The authentication information of the client also disappears , And the client information is written in the program , It is inconvenient to maintain , Every time you modify, you need to restart the service , If the above information is stored in the database, the above problem can be solved , We can save the data to noSql
Or other databases ,SpringOauth2
It also provides us with a database solution .
Here is the address of the last article :
Two 、 Database storage mode
Database we choose Mysql
Storing our data , First, create a new storage client information in the database , And authorization code table :
CREATE TABLE `oauth_client_details` (
`client_id` varchar(255) NOT NULL COMMENT ' Client identity ',
`resource_ids` varchar(255) DEFAULT NULL COMMENT ' Access resource list ',
`client_secret` varchar(255) DEFAULT NULL COMMENT ' Client secret key ',
`scope` varchar(255) DEFAULT NULL COMMENT ' Scope of Authorization ',
`authorized_grant_types` varchar(255) DEFAULT NULL COMMENT ' Allow authorization type ',
`web_server_redirect_uri` varchar(255) DEFAULT NULL COMMENT ' Client redirection URI',
`authorities` varchar(255) DEFAULT NULL COMMENT ' The permission value owned by the client ',
`access_token_validity` int(11) DEFAULT NULL COMMENT ' Set the client's access_token Effective time value of ( Company : second )',
`refresh_token_validity` int(11) DEFAULT NULL COMMENT ' Set the client's refresh_token Effective time value of ( Company : second ',
`additional_information` text COMMENT ' This is a reserved field , stay Oauth There is no actual use in the process of , Optional , But if the setting is , Must be JSON Formatted data ,',
`create_time` timestamp NULL DEFAULT NULL,
`archived` tinyint(1) DEFAULT NULL COMMENT ' Used to identify whether the client is archived ( That is to achieve logical deletion ), The default value is ’0’( I.e. not filed )',
`trusted` tinyint(1) DEFAULT NULL COMMENT ' Set whether the client is trusted , The default is ’0’( That is, untrusted ,1 For the trusted )',
`autoapprove` varchar(255) DEFAULT NULL COMMENT ' Set whether the user automatically Approval operation , The default value is ‘false’, Optional values include ‘true’,‘false’, ‘read’,‘write’. ',
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Add two pieces of client information to the table :
INSERT INTO `testdb`.`oauth_client_details` (`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `create_time`, `archived`, `trusted`, `autoapprove`) VALUES ('c1', 'res1', '$2a$10$UmGvnYkVcMwvv.Tki2hd2.1TwSbB3FmQuJDduq0cnIVoCYkvAh5Ey', 'all', 'client_credentials,password,authorization_code,implicit,refresh_token,sms_code', 'http://www.baidu.com', NULL, '259200', '31536000', NULL, '2020-07-12 21:55:48', '0', '0', 'false');
INSERT INTO `testdb`.`oauth_client_details` (`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `create_time`, `archived`, `trusted`, `autoapprove`) VALUES ('c2', 'res2', '$2a$10$UmGvnYkVcMwvv.Tki2hd2.1TwSbB3FmQuJDduq0cnIVoCYkvAh5Ey', 'ROLE_API', 'client_credentials,password,authorization_code,implicit,refresh_token', 'http://www.baidu.com', NULL, '259200', '31536000', NULL, '2020-07-12 21:55:48', '0', '0', 'false');
Next, create a table for storing authorization codes :
CREATE TABLE `oauth_code` (
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT ' Data creation time ',
`code` varchar(255) DEFAULT NULL COMMENT ' It is generated by the storage server system code Value ( unencrypted )',
`authentication` blob COMMENT ' Storage will AuthorizationRequestHolder.java Binary data after object serialization .',
KEY `code_index` (`code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
The authorization code is generated every time the customer applies for authorization , We don't need to add any data .
Authentication service modification
Next, add mysql
And mybatis-plus
Dependence :
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
In the configuration file , Add information about linked databases :
server:
port: 8020
spring:
datasource:
url: jdbc:mysql://192.168.40.1:3307/testdb?useUnicode=true&characterEncoding=utf8
username: root
password: root123
type: com.alibaba.druid.pool.DruidDataSource
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.bxc.auth.entity
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
Now we mainly focus on AuthorizationServer
In the configuration class , Add one ClientDetailsService
The return method of , It uses SpringOauth2
Help us pack up JdbcClientDetailsService
Object to build a ClientDetailsService
Replace the original default ClientDetailsService
.
We also use the authorization code JdbcAuthorizationCodeServices
Replace the original InMemoryAuthorizationCodeServices
.
The following is the modified configuration class :
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
@Qualifier("jdbcClientDetailsService")
private ClientDetailsService clientDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthorizationCodeServices authorizationCodeServices;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Autowired
UserService userService;
@Autowired
PasswordEncoder passwordEncoder;
@Bean("jdbcClientDetailsService")
public ClientDetailsService clientDetailsService(DataSource dataSource) {
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setPasswordEncoder(passwordEncoder);
return clientDetailsService;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Bean
public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {
return new JdbcAuthorizationCodeServices(dataSource);// Set how the authorization code of the authorization code mode is accessed
}
@Bean
public AuthorizationServerTokenServices tokenService() {
DefaultTokenServices service = new DefaultTokenServices();
service.setClientDetailsService(clientDetailsService);
service.setSupportRefreshToken(true);
service.setTokenStore(tokenStore);
// Token enhancement
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
// Content enhancement
tokenEnhancers.add(tokenEnhancer());
tokenEnhancers.add(accessTokenConverter);
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
service.setTokenEnhancer(tokenEnhancerChain);
service.setAccessTokenValiditySeconds(7200); // Token default validity 2 Hours
service.setRefreshTokenValiditySeconds(259200); // Refresh token default validity 3 God
return service;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager)// Authentication manager
.authorizationCodeServices(authorizationCodeServices)// Authorization code service
.tokenServices(tokenService())// Token management service
.allowedTokenEndpointRequestMethods(HttpMethod.POST);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()") //oauth/token_key It's public
.checkTokenAccess("permitAll()") //oauth/check_token Open
.allowFormAuthenticationForClients(); // Forms authentication ( Claim Token )
}
/**
* JWT Content enhancement
*/
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("userid", -1);
Authentication auth = authentication.getUserAuthentication();
if (auth != null) {
UserEntity user = (UserEntity) auth.getPrincipal();
additionalInfo.put("userid", user.getId());
}else {
String clientId = authentication.getOAuth2Request().getClientId();
String grantType = authentication.getOAuth2Request().getRequestParameters().get("grant_type");
if (Objects.equals(clientId, "c1") && Objects.equals(grantType, "client_credentials")) {
additionalInfo.put("userid", "root");
}
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
}
}
The following are the main modifications :
3、 ... and 、 Authorization code test
First we use c1 Client application authorization code :
http://localhost:8020/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com
Login carefully :
to grant authorization :
You can see the returned authorization code in the address bar :
Next, you can see the storage of the database :
Now use this authentication code to apply for a token :
Then check the data in the database :
From the above demonstration, we can see , Both the client and the authorization code have worked .
Love little buddy can pay attention to my personal WeChat official account. , Get more learning materials !
边栏推荐
- Using the ethtool command by example
- 88. Merge two ordered arrays
- Kubernetes notes (I) kubernetes cluster architecture
- [teacher Zhao Yuqiang] MySQL flashback
- pytorch 搭建神经网络最简版
- Kubernetes notes (VIII) kubernetes security
- @Import annotation: four ways to import configuration classes & source code analysis
- PMP笔记记录
- 2022.DAY592
- Sorry, this user does not exist!
猜你喜欢
项目总结--2(Jsoup的基本使用)
理解 期望(均值/估计值)和方差
Why is the website slow to open?
Kubernetes notes (I) kubernetes cluster architecture
Today, many CTOs were killed because they didn't achieve business
PHP notes are super detailed!!!
Pytorch dataloader implements minibatch (incomplete)
理解 YOLOV1 第一篇 预测阶段
Solve the problem of automatic disconnection of SecureCRT timeout connection
Final review (Day5)
随机推荐
Kubernetes notes (II) pod usage notes
C 语言文件操作函数大全 (超详细)
[teacher Zhao Yuqiang] Cassandra foundation of NoSQL database
Solve the problem of automatic disconnection of SecureCRT timeout connection
Using the ethtool command by example
[teacher Zhao Yuqiang] the most detailed introduction to PostgreSQL architecture in history
一起上水碩系列】Day 9
It is said that the operation and maintenance of shell scripts are paid tens of thousands of yuan a month!!!
Es remote cluster configuration and cross cluster search
[teacher Zhao Yuqiang] index in mongodb (Part 2)
一起上水硕系列】Day 9
Kubernetes notes (VIII) kubernetes security
Virtual memory technology sharing
Understand one-way hash function
[function explanation (Part 1)] | | knowledge sorting + code analysis + graphic interpretation
Skywalking8.7 source code analysis (I): agent startup process, agent configuration loading process, custom class loader agentclassloader, plug-in definition system, plug-in loading
卷积神经网络CNN中的卷积操作详解
[advanced pointer (1)] | detailed explanation of character pointer, pointer array, array pointer
Kubernetes resource object introduction and common commands (V) - (configmap)
Alibaba cloud Alipay sandbox payment