spring boot 2.1.6.RELEASE配oauth2-2.0版本

  • maven ->pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mingjia</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dataControl</name>
    <description>data control content</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Edgware.SR1</spring-cloud.version>
        <spring-boot.version>2.2.0.RELEASE</spring-boot.version>
        <gson.version>2.8.5</gson.version>
        <querydsl.version>4.2.1</querydsl.version>
        <org.mapstruct.version>1.3.0.Beta1</org.mapstruct.version>
        <lombok.version>1.18.2</lombok.version>
        <mysql-connector-java.version>8.0.16</mysql-connector-java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>

        <!-- 架構插件:映射  -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
            <scope>provided</scope>
        </dependency>



        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.0.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>


        <!-- jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>



        <!-- swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.8.0</version>
        </dependency>


        <!-- json -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>



        <!--QueryDSL支持-->
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
        </dependency>
        <!--mysql驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector-java.version}</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>${querydsl.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
            </resource>
        </resources>
    </build>


</project>

下面是oauth2相關配置,公4個class

  1. AuthenticationBeanConfig
package com.mingjia.data_control.config.oauth;


import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;

@Configuration
public class AuthenticationBeanConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    @ConditionalOnMissingBean(PasswordEncoder.class)
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @ConditionalOnMissingBean(ClientDetailsService.class)
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }
}

  1. OAuth2ServerConfig
package com.mingjia.data_control.config.oauth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AccessTokenConverter accessTokenConverter;

    @Autowired
    private ClientDetailsService clientDetails;

    // 配置令牌端點(Token Endpoint)的安全約束
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
                // code授權添加
                .realm("oauth2-resources")
                // 開啓/oauth/token_key驗證端口無權限訪問
                .tokenKeyAccess("permitAll()")
                // 接口/oauth/check_token允許檢查令牌
                .checkTokenAccess("isAuthenticated()")
                // 使/oauth/token支持client_id以及client_secret作登錄認證
                .allowFormAuthenticationForClients()
                // 密碼編碼器
                .passwordEncoder(passwordEncoder);
    }

    // 配置授權(authorization)以及令牌(token)的訪問端點和令牌服務(token services)
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        endpoints
                // 認證管理器
                .authenticationManager(authenticationManager)
                // 允許 GET、POST 請求獲取 token,即訪問端點:oauth/token
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                // 要使用refresh_token的話,需要額外配置userDetailsService
                .userDetailsService(userDetailsService)
                // 指定token存儲位置
                .tokenStore(tokenStore)
                // 配置JwtAccessToken轉換器
                .accessTokenConverter(accessTokenConverter)
                // 客戶端詳細信息服務的基本實現 這裏使用JdbcClientDetailsService
                .setClientDetailsService(clientDetails);
    }

    // 配置客戶端詳情服務
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 內存模式
        /**
         * clients.inMemory().withClient("demoApp").secret(bCryptPasswordEncoder.encode("demoAppSecret"))
         .redirectUris("http://baidu.com")// code授權添加
         .authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
         // scopes的值就是all(全部權限),read,write等權限。就是第三方訪問資源的一個權限,訪問範圍
         .scopes("all")
         // 這個資源服務的ID,這個屬性是可選的,但是推薦設置並在授權服務中進行驗證。
         .resourceIds("oauth2-resource")
         // 設置accessTokenValiditySeconds屬性來設置Access Token的存活時間。
         .accessTokenValiditySeconds(1200)
         // 設置refreshTokenValiditySeconds屬性來設置refresh Token的存活時間。
         .refreshTokenValiditySeconds(50000);
         */

        // 數據庫模式
        clients.withClientDetails(clientDetails); // 表中存儲的secret值是加密後的值,並非明文;
    }
}

  1. ResourceServerConfig
package com.mingjia.data_control.config.oauth;


import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(HttpMethod.GET,"/api/**").hasRole("ADMINISTRATOR")
                .antMatchers("/oauth/confirm_access").permitAll()
                .antMatchers("/**/*.js").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                .and()
                .requestMatchers().antMatchers("/api/**").and().authorizeRequests().antMatchers("/api/**").authenticated();
    }
}
  1. SecurityConfig
package com.mingjia.data_control.config.oauth;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers()
                .antMatchers("/oauth/**", "/login/**", "/logout/**")
                .and()
                .authorizeRequests()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .cors().disable();
    }

    @Bean
    public TokenStore tokenStore() {
        // 使用redis存儲token信息
        RedisTokenStore redisTokenStore = new RedisTokenStore(connectionFactory);
        return redisTokenStore;

        // 使用jwt內存存儲token信息
//		JwtTokenStore jwtTokenStore = new JwtTokenStore(accessTokenConverter());
//		return jwtTokenStore;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("healthy");
        return converter;
    }


    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

    /**
     * *需要配置這個支持password模式 support password grant type
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    public static void main(String[] args) {
        String encode = new BCryptPasswordEncoder().encode("dataApp");
        String password = new BCryptPasswordEncoder().encode("123456");

        System.out.println("encode:"+encode);
        System.out.println("password"+password);
    }
}

創建entity DataUser 要繼承UserDetails

package com.mingjia.data_control.modules.base_module.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 自定義UserDetails類 攜帶User實例
 */
@Getter
@Setter
@Entity
public class DataUser extends BaseModel implements UserDetails, Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    private String username;

    private String password;


    /**
     * 是否激活
     */
    @Transient
    private Boolean active = true;



    /**
     * 角色
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "data_user_role_map",
            joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<DataRole> roles = new HashSet<>();





    /**
     * implements UserDetails
     */
    @Override
    public String getUsername() {
        return username;
    }

    @JsonIgnore
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @JsonIgnore
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @JsonIgnore
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @JsonIgnore
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return getGrantedAuthorities(this.getPermissions(roles));
    }

    private List<GrantedAuthority> getGrantedAuthorities(List<String> getPermissions) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String permission : getPermissions) {
            authorities.add(new SimpleGrantedAuthority(permission));
        }
        return authorities;
    }

    private List<String> getPermissions(Collection<DataRole> roles) {
        List<String> permissions = new ArrayList<>();
        for (DataRole role : roles) {
			permissions.add("ROLE_" + role.getType().toString().toUpperCase());
            for (DataPermission item : role.getPermissions()) {
				permissions.add("OP_" +item.getCode().toUpperCase());
            }
        }

        return permissions;
    }


    @Override
    public boolean isEnabled() {
        return active;
    }

    private static List<GrantedAuthority> mapToGrantedRoles(List<DataRole> authorities) {
        return authorities.stream()
                .map(authority -> new SimpleGrantedAuthority(authority.getName()))
                .collect(Collectors.toList());
    }
}

主要驗證口:DataUserServiceImpl ,其他的IDataUserService我就不貼了

package com.mingjia.data_control.modules.base_module.service.impl;


import com.mingjia.data_control.modules.base_module.entity.DataPermission;
import com.mingjia.data_control.modules.base_module.entity.DataRole;
import com.mingjia.data_control.modules.base_module.entity.DataUser;
import com.mingjia.data_control.modules.base_module.service.IDataUserService;
import com.mingjia.data_control.modules.base_module.service.query.DataUserQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


@Component("userDetailsService")
public class DataUserServiceImpl extends BaseServiceImpl<DataUser, Long> implements IDataUserService {

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        Optional<DataUser> optionalDataUser = this.findOne(DataUserQuery.findByUserName(username));
        DataUser dataUser = this.checkOptional(optionalDataUser);
        /**
         * isEnabled 賬戶是否啓用
         * isAccountNonExpired 賬戶沒有過期
         * isCredentialsNonExpired 身份認證是否是有效的
         * isAccountNonLocked 賬戶沒有被鎖定
         * 對於 isAccountNonLocked 和 isEnabled 沒有做業務處理,只是拋出了對於的異常信息;
         */
        List<String> permissions = new ArrayList<>();
        for (DataRole role : dataUser.getRoles()) {
            permissions.add("ROLE_" + role.getType());
            for (DataPermission item : role.getPermissions()) {
                permissions.add("OP_" + item.getType() + "_" + item.getCode().toUpperCase());

            }
        }
        String authorityString = String.join(",",permissions);
        return new User(username, dataUser.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(authorityString));
    }
}

基本就完成了

application.properties配置

spring.application.name=oauth2-demo
server.port=8090

logging.level.root=info





###################################
# 數據庫 MYSQL 設置
###################################
spring.datasource.url=jdbc:mysql://localhost/data_control?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Hibernate ORM 設置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

spring.main-server.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.main-server.datasource.initial-size=5
spring.main-server.datasource.max-active=20
spring.main-server.datasource.min-idle=5
spring.main-server.datasource.max-wait=60000
spring.main-server.datasource.validation-query=SELECT 1 FROM DUAL
spring.main-server.datasource.test-on-borrow=false
spring.main-server.datasource.test-on-return=false
spring.main-server.datasource.test-while-idle=true
spring.main-server.datasource.time-between-eviction-runs-millis=60000
spring.main-server.datasource.min-evictable-idle-time-millis=300000
spring.main-server.datasource.filter.stat.log-slow-sql=true



# Redis數據庫索引(默認爲0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=localhost
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=5000


數據庫創建 - data_control

需要生成一個表oauth_client_details

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(48) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `access_token_validity` int(11) NULL DEFAULT NULL,
  `refresh_token_validity` int(11) NULL DEFAULT NULL,
  `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES ('demoApp',
 'oauth2-resource', '$2a$10$z6DXhwPrzQe4wk9nGmqLvO6zQzYEAYscmNaAaDTDVhhuJGrhqZzk.',
 'all', 'authorization_code,client_credentials,password,refresh_token',
  'http://baidu.com', 'ROLE_CLIENT', 3600, 3600, NULL, NULL);

SET FOREIGN_KEY_CHECKS = 1;

完成樣子
在這裏插入圖片描述在這裏插入圖片描述
找不到可以碼雲搜,實測可用
在這裏插入圖片描述
我用的是碼雲gitee
項目下載地址:
https://gitee.com/mingjia_xu/data_control/repository/archive/master.zip

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章