preface
In the last article, we set up a process for client_credentials with Oauth2 authorization in the simplest way possible. Now, on this basis, we will go one step further, we store the client information and token in the database, convenient for us to manage. And the password needs to be secure, so it needs to be encrypted. With a clear goal, let’s do it!
Client&token is stored in the database
Steps:
- Database preparation: Create only the tables we need to use
- Add database dependencies: use the mysql database
- Oauth Storage configuration Settings
- validation
Database preparation
In the local database, create two tables:
- A table stores client information
- The other table stores the tokens
# Client informationcreate table oauth_client_details
(
client_id VARCHAR(256) PRIMARY KEY comment 'Required, Oauth2 client_id',
resource_ids VARCHAR(256) comment 'Optional, set of resource ids, separated by commas.',
client_secret VARCHAR(256) comment 'Required, Oauth2 client_secret'.scope VARCHAR(256) comment 'Mandatory, Oauth2 permission scope, such as read, write, etc. Customizable',
authorized_grant_types VARCHAR(256) comment 'Mandatory, Oauth2 authorization type, supported types: authorization_code,password,refresh_token,implicit,client_credentials, separated by commas.',
web_server_redirect_uri VARCHAR(256) comment 'Optional, client redirection URI, this field is required when grant_type is authorization_code or implicit',
authorities VARCHAR(256) comment 'Optional, specify the client's Spring Security permission value',
access_token_validity INTEGER comment 'optional, access_token value (unit: second), the duration of your framework (refreshTokenValiditySeconds) don't fill in the default 12 hours',
refresh_token_validity INTEGER comment 'optional, refresh_token effective time value (unit: second), not fill in the framework (refreshTokenValiditySeconds) default 30 days',
additional_information VARCHAR(4096) comment 'Reserved field, format must be JSON',
autoapprove VARCHAR(256) comment 'This field applies to whether the user automatically approves the action when grant_type="authorization_code"'); # token storagecreate table oauth_access_token
(
token_id VARCHAR(256) comment 'ACCESS_token stored after MD5 encryption',
token BLOB comment 'Binary data format for access_token serialization',
authentication_id VARCHAR(256) PRIMARY KEY comment 'primary key, its value is based on the current username (if any), client_id and scope through the MD5 encryption generated, concrete implementation see DefaultAuthenticationKeyGenerator',
user_name VARCHAR(256),
client_id VARCHAR(256),
authentication BLOB comment 'Binary data after serialization of OAuth2Authentication object',
refresh_token VARCHAR(256) comment 'MD5 encrypted data for refresh_token'
);
Copy the code
After that, we need to add custom client information. The client information added in this demo is as follows (still in accordance with the principle of not configuring as much as possible) :
INSERT INTO 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, autoapprove) VALUES ('gold'.'res'.'{noop}123456'.'write'.'client_credentials'.null.null.null.null.null.null);
Copy the code
instructions
- In the official source code, there is a corresponding schema. SQL file. Here, only the tables involved in our example are created
- For two table operations, we can look at these two classes: JdbcClientDetailsService & JdbcTokenStore
- In addition, this example adds resource_ids, note in the configuration
ResourceServerSecurityConfigurer
In the corresponding
Pom
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
Copy the code
The authentication server code is modified
@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
private final DataSource dataSource;
public MyAuthorizationServerConfigurer(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(newJdbcTokenStore(dataSource)); }}Copy the code
The above code only shows the changed part, modify the client configuration and tokenStore configuration, add data source can be done
The request token
The following request is made in Postman. Base_url is the set global variable, which is actually http://127.0.0.1:8080
Access to resources
Observation database
Since the token is stored in binary form in the database, we can see from the client_id data that it is the client we just requested.
So far we have been implemented, the client and token information stored in the database, so that we are more convenient to the client and token data management. But it is not secure for a database to store plaintext passwords, so next, we encrypt client_secret.
Client_secret encryption
Configuration passwordEncoder
You can check the PasswordEncoderFactories (MD5, SHA, bcrypt) with SpringBoot Oauth. So direct configuration support passwordEncoder of all algorithms, namely DelegatingPasswordEncoder.
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder());
}
Copy the code
Encryption client_secret
Since we use bcrypt encryption this time, we can directly find the BCryptPasswordEncoder, which can encrypt our password and store the password in the database.
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PasswordEncodeUtil {
private static final BCryptPasswordEncoder bcryptEncoder = new BCryptPasswordEncoder();
public static String bcryptEncode(String password) {
return bcryptEncoder.encode(password);
}
public static String genOauthEncodePwd(String password) {
return "{bcrypt}" + bcryptEncode(password);
}
public static void main(String[] args) {
String oriPwd = "123456"; System.out.println(genOauthEncodePwd(oriPwd)); }}Copy the code
Old password: 123456
Encrypted password: {bcrypt} 2 a2a2a10 $NPxtsEUMmBGTlzVXlT. ScubSCXNEDlBAq2r2t7iQFB /. RaNBlh0nO
Note: The encryption password is prefixed with curly braces “{XXX}”, which specifies the encryption algorithm name. Because the framework supports multiple encryption algorithms, it must be prefixed with the specified encryption algorithm.
Request to Obtain token
The following request is made in Postman. Base_url is the set global variable, which is actually http://127.0.0.1:8080
Request resources
summary
In this paper, client and token information is stored in the database in the mode of client_credentials for easy management. Meanwhile, in order to ensure password security, client_secret is encrypted with bcrypt algorithm and stored in the database. With the foundation of the previous article, this article as a whole looks quite simple. Let’s do it, guys!
Personal level is limited, welcome to correct, exchange oh ~~~
The demo:Github.com/goldpumpkin…
Reference:
- Spring-oauth-server database table description