SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务

Posted 1156184981651a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务相关的知识,希望对你有一定的参考价值。

开发背景什么的我就不介绍了官网介绍:https://spring.io/guides/tutorials/spring-boot-oauth2/  既然大家需要用到这个技术 直接撸代码吧!!!

1.创建maven springboot项目 添加相关依赖 采用最新的版本(相关依赖版本如下)

<!--spring-boot 版本-->
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.2.5.RELEASE</version>
</parent>

<!--spring-cloud  spring cloud alibaba版本-->

<dependencyManagement>
        <dependencies>
            <!--整合spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--整合spring cloud alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>


<!--整合oauth2-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.创建oauth2 认证服务器配置类

/**
 *
 * @Description Authorization配置
 * @Date 2020/6/24 11:36
 * @Author Jax
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {


    @Autowired
    private PasswordEncoder passwordEncoder;

   /**
     * 这里先把服务写到内存里面 后续配置到mysql
     * 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
     * see:org.springframework.security.oauth2.provider.authentication
     * 我这里假设我现在有一个游戏微服务game_client  一个网关微服务gateway_client
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("game_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)//token的失效时间 单位秒
                .resourceIds("game-service")
                .scopes("read", "write")//控制发出去的服务令牌权限
                .authorizedGrantTypes("password")//授权方式
                .and()
                .withClient("gateway_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)
                .resourceIds("gateway")
                .scopes("read", "write")
                .authorizedGrantTypes("password");
    }


//OAuth2为我们提供了四种授权方式:
//1、授权码模式(authorization code)
     //授权码相对其他三种来说是功能比较完整、流程最安全严谨的授权方式,通过客户端的后台服务器与服务提供商的认证服务器交互来完成
//2、简化模式(implicit)
     //这种模式不通过服务器端程序来完成,直接由浏览器发送请求获取令牌,令牌是完全暴露在浏览器中的,这种模式极力不推崇
//3、密码模式(resource owner password credentials)
     //密码模式也是比较常用到的一种,客户端向授权服务器提供用户名、密码然后得到授权令牌。这种模式不过有种弊端,我们的客户端需要存储用户输入的密码,但是对于用户来说信任度不高的平台是不可能让他们输入密码的
//4、客户端模式(client credentials)
     //客户端模式是客户端以自己的名义去授权服务器申请授权令牌,并不是完全意义上的授权。

}

3.需要配置认证服务器知道可以让哪些用户来访问我 即authenticationManager配置

/**
 *
 * @Description Authorization配置
 * @Date 2020/6/24 11:36
 * @Author Jax
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    


   /**
     * 这里先把服务写到内存里面 生产环境肯定是不行的 需要配置mysql参考我下面的配置
     * 建议先把流程走通 再倒回来 配置mysql持久化
     * 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
     * see:org.springframework.security.oauth2.provider.authentication
     * 我这里假设我现在有一个游戏微服务game_client  一个网关微服务gateway_client
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("game_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)
                .resourceIds("gateway", "game-service")
                .scopes("read", "write")
                .authorizedGrantTypes("password")
                .and()
                .withClient("gateway_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)
                .resourceIds("gateway", "game-service")
                .scopes("read", "write")
                .authorizedGrantTypes("password");
    }


    /**
     * 配置哪些可以访问认证服务器
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager); //authenticationManager校验传递进来的用户是否合法
    }


}

3.1. 上面配置是为了测试 放在了内存里 然而这样在生产环境肯定是不行的!因为我们要对客户开放注册Client!我们要实现Client的注册,动态的加载到Oauth服务中。所以要实现Client的持久化,这里我们使用Mysql 建议直接先跳过这里的步骤 先把流程走通 再倒回来 配置mysql持久化!!!

3.2. pom文件添加依赖

```
<!--整合jdbc 实现服务数据持久化-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql connector -->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>
```

3.3. 导入sql脚本(这里使用mysql)

```sql
/*
 Navicat Premium Data Transfer

 Source Server         : 192.168.2.230
 Source Server Type    : MySQL
 Source Server Version : 50725
 Source Host           : 192.168.2.230:3306
 Source Schema         : oauth

 Target Server Type    : MySQL
 Target Server Version : 50725
 File Encoding         : 65001

 Date: 02/07/2020 11:44:17
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for authority
-- ----------------------------
DROP TABLE IF EXISTS `authority`;
CREATE TABLE `authority`  (
  `id` bigint(11) NOT NULL COMMENT ‘权限id‘,
  `authority` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘权限‘,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for credentials
-- ----------------------------
DROP TABLE IF EXISTS `credentials`;
CREATE TABLE `credentials`  (
  `id` bigint(11) NOT NULL COMMENT ‘凭证id‘,
  `enabled` tinyint(1) NOT NULL COMMENT ‘是否可用‘,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘用户名‘,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘密码‘,
  `version` int(11) NULL DEFAULT NULL COMMENT ‘版本号‘,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for credentials_authorities
-- ----------------------------
DROP TABLE IF EXISTS `credentials_authorities`;
CREATE TABLE `credentials_authorities`  (
  `credentials_id` bigint(20) NOT NULL COMMENT ‘凭证id‘,
  `authorities_id` bigint(20) NOT NULL COMMENT ‘权限id‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token`  (
  `token_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密的access_token的值‘,
  `token` longblob NULL COMMENT ‘OAuth2AccessToken.java对象序列化后的二进制数据‘,
  `authentication_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密过的username,client_id,scope‘,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录的用户名‘,
  `client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端ID‘,
  `authentication` longblob NULL COMMENT ‘OAuth2Authentication.java对象序列化后的二进制数据‘,
  `refresh_token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密的refresh_token的值‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_approvals
-- ----------------------------
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals`  (
  `userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录的用户名‘,
  `clientId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端ID‘,
  `scope` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘申请的权限范围‘,
  `status` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘状态(Approve或Deny)‘,
  `expiresAt` datetime(0) NULL DEFAULT NULL COMMENT ‘过期时间‘,
  `lastModifiedAt` datetime(0) NULL DEFAULT NULL COMMENT ‘最终修改时间‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘客户端ID‘,
  `resource_ids` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘资源ID集合,多个资源时用逗号(,)分隔‘,
  `client_secret` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端密匙‘,
  `scope` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端申请的权限范围‘,
  `authorized_grant_types` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端支持的grant_type‘,
  `web_server_redirect_uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘重定向URI‘,
  `authorities` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端所拥有的Spring Security的权限值,多个用逗号(,)分隔‘,
  `access_token_validity` int(11) NULL DEFAULT NULL COMMENT ‘访问令牌有效时间值(单位:秒)‘,
  `refresh_token_validity` int(11) NULL DEFAULT NULL COMMENT ‘更新令牌有效时间值(单位:秒)‘,
  `additional_information` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘预留字段‘,
  `autoapprove` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘用户是否自动Approval操作‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_client_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token`  (
  `token_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密的access_token值‘,
  `token` longblob NULL COMMENT ‘OAuth2AccessToken.java对象序列化后的二进制数据‘,
  `authentication_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密过的username,client_id,scope‘,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录的用户名‘,
  `client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端ID‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_code
-- ----------------------------
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code`  (
  `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘授权码(未加密)‘,
  `authentication` varbinary(255) NULL DEFAULT NULL COMMENT ‘AuthorizationRequestHolder.java对象序列化后的二进制数据‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_refresh_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token`  (
  `token_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密过的refresh_token的值‘,
  `token` longblob NULL COMMENT ‘OAuth2RefreshToken.java对象序列化后的二进制数据 ‘,
  `authentication` longblob NULL COMMENT ‘OAuth2Authentication.java对象序列化后的二进制数据‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘用户名‘,
  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘密码‘,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = ‘用户信息表‘ ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

```

3.4. 插入2条测试数据 即上面配置在内存的数据 密码是123456 我这里用passwordEncoder编译了一下

```sql
public static void main(String[] args) {
        System.out.println(new BCryptPasswordEncoder().encode("123456"));
    }



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 (‘game_client‘, ‘game-service,gateway‘, ‘$2a$10$HT1fF.8WhP08YblPWphCMeuzJM7AP68LR86uC/kX9tbXIHOxBbkMW‘, ‘read,write‘, ‘password,client_credentials‘, ‘http://127.0.0.1‘, ‘ROLE_PROJECT_ADMIN‘, 7200, 1800, NULL, ‘true‘);
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 (‘gateway_client‘, ‘gateway‘, ‘$2a$10$HT1fF.8WhP08YblPWphCMeuzJM7AP68LR86uC/kX9tbXIHOxBbkMW‘, ‘read,write‘, ‘password‘, ‘http://127.0.0.1‘, ‘ROLE_PROJECT_ADMIN‘, 7200, 1800, NULL, ‘true‘);

```

3.5. 编写yml配置

```Swift
spring:  
    application:
      name: auth
    datasource:
        url: jdbc:mysql://192.168.2.130:3306/你的数据库?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=UTC
        username: root
        password: ****
        driver-class-name: com.mysql.cj.jdbc.Driver
```

3.6.编写Oauth2AuthServiceConfig配置

/**
 *
 * @Description Authorization配置
 * @Date 2020/6/24 11:36
 * @Author Jax
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {

    //注入数据源
    @Autowired
    private DataSource dataSource;

   /**
     * 这里配置到mysql 数据跟写入内存一样的 不影响后面的测试
     * 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
     * see:org.springframework.security.oauth2.provider.authentication
     * 我这里假设我现在有一个游戏微服务game_client  一个网关微服务gateway_client
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

    //需要把token的信息放进mysql 生成的token 存放的表:oauth_access_token
    @Bean
    public TokenStore jdbcTokenStore() {
        //使用数据库来操作token
        return new JdbcTokenStore(dataSource);
    }

 /**
     * 配置哪些可以访问认证服务器
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                 .tokenStore(jdbcTokenStore())//需要告诉我们的服务器需要用JdbcTokenStore来存储我们的token
                 .authenticationManager(authenticationManager); //authenticationManager校验传递进来的用户是否合法
    }

**                                                                                 至此mysql 持久化配置+管理token完成!!!**

  • 翻外篇 如果想使用JWT来生成 管理token 应该怎么来改造 建议先把第一遍流程走通再倒回来看这些配置!!!

    /**
     *
     * @Description Authorization配置
     * @Date 2020/6/24 11:36
     * @Author Jax
     */
    @Configuration
    @EnableAuthorizationServer
    public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
    
        //注入数据源
        @Autowired
        private DataSource dataSource;
    
       /**
         * 这里配置到mysql
         * 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
         * see:org.springframework.security.oauth2.provider.authentication
         * 我这里假设我现在有一个游戏微服务game_client  一个网关微服务gateway_client
         * @param clients
         * @throws Exception
         */
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.jdbc(dataSource);
        }
    
        //把之前JdbdTokenStore 改成JwtTokenStore 就可以了
        @Bean
        public TokenStore jwtTokenStore() {
            //使用Jwt操作token
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
    
    
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            //推荐使用证书作为生成token的密钥
            //KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("aa.key"),"123456".toCharArray());
            //converter.setKeyPair(keyStoreKeyFactory.getKeyPair("aa"));
            converter.setSigningKey("abcdefg");//这里采用abcdefg作为生成密钥的key
            return converter;
        }
    
     /**
         * 配置哪些可以访问认证服务器
         *
         * @param endpoints
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints
                     .tokenEnhancer(jwtAccessTokenConverter())//配置token方式
                     .tokenStore(jwtTokenStore())//需要告诉我们的服务器需要用jwtTokenStore来存储我们的token
                     .authenticationManager(authenticationManager); //authenticationManager校验传递进来的用户是否合法
        }
    
    
        /**
         * 配置验证令牌的条件(即满足什么样的条件才能找我验证令牌 不是随便拿token也来验证)
         * 这里都先做一个最基本的配置
         *
         * @param security
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security
                    .tokenKeyAccess("isAuthenticated()")    //暴露signingKey 经过认证之后服务才能拿到这个签名的key
                    .checkTokenAccess("isAuthenticated()");//检验服务验证的规则 必须是经过验证的 用户名 密码 就是上面所配置的 game_client 123456 ..... 我才给你验证令牌
        }
    
    
    
    
    }
    

**                                                                         OK改造成JWT 生成token 完成!**

4.写好前面的配置 这个时候我们需要来配置低3步中注入的AuthenticationManager  PasswordEncoder

/**
 * @Description 配置认证服务器WEB配置
 * @Date 2020/6/24 11:49
 * @Author Jax
 */
@Configuration
@EnableWebSecurity
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //根据用户名获取用户详细信息 接下来 我们需要来实现这个方法 (第5步)
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

    /**
     * 暴露AuthenticationManager
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

5.实现UserDetailsService这个方法 编写代码

/**
 * @Description 获取用户信息
 * @Date 2020/6/24 12:31
 * @Author Jax
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

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

        //TODO 需要去数据库查询当前用户信息 这里方便测试 采用org.springframework.security.core.userdetails 来构建一个用户
        return User.withUsername(username)  //构建一个用户所必须的3个条件 用户名 密码 权限 
                .password(passwordEncoder.encode("123456"))
                .authorities("ROLE_ADMIN")
                .build();
    }
}

6.完成上述步骤 合法的应用信息(3步) 合法的用户信息 现在我们都配置好了 接下来我们应该配置 微服务验证令牌的相关配置了 接着上面第3步 继续写代码

/**
 *
 * @Description Authorization配置
 * @Date 2020/6/24 11:36
 * @Author Jax
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    


   /**
     * 这里先把服务写到内存里面
     * 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
     * authorizedGrantTypes类型支持https://www.cnblogs.com/strugglepcx/p/5139013.html
     * see:org.springframework.security.oauth2.provider.authentication
     * 我这里假设我现在有一个游戏微服务game_client  一个网关微服务gateway_client
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("game_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)
                .resourceIds("gateway", "game-service")
                .scopes("read", "write")
                .authorizedGrantTypes("password")
                .and()
                .withClient("gateway_client")
                .secret(passwordEncoder.encode("123456"))
                .accessTokenValiditySeconds(3600)
                .resourceIds("gateway", "game-service")
                .scopes("read", "write")
                .authorizedGrantTypes("password");
    }


    /**
     * 配置哪些可以访问认证服务器
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager); //authenticationManager校验传递进来的用户是否合法
    }


    /**
     * 配置验证令牌的条件(即满足什么样的条件才能找我验证令牌 不是随便拿token也来验证)
     * 这里都先做一个最基本的配置
     *
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("isAuthenticated()");//检验服务验证的规则 必须是经过验证的 用户名 密码 就是上面所配置的 game_client 123456 ..... 我才给你验证令牌
    }



}

7.启动OAuth 微服务 使用postman访问localhost:你的端口/oauth/token 进行测试 获取token

技术图片

技术图片

返回结果如下

技术图片

OK SpringCloudAlibaba+Zuul+OAuth2 (一) 搭建认证微服务 完成!

 

 

 

http://www.1994july.club/?p=52010
http://www.1994july.club/?p=52040
http://www.1994july.club/?p=51992
http://www.1994july.club/?p=51881
http://www.1994july.club/?p=52006
http://www.1994july.club/?p=52080
http://www.1994july.club/?p=51962
http://www.1994july.club/?p=51936
http://www.1994july.club/?p=52073
http://www.1994july.club/?p=51975
http://www.1994july.club/?p=51954
http://www.1994july.club/?p=51883
http://www.1994july.club/?p=51988
http://www.1994july.club/?p=51915
http://www.1994july.club/?p=51950
http://www.1994july.club/?p=52115
http://www.1994july.club/?p=52024
http://www.1994july.club/?p=51918
http://www.1994july.club/?p=51980
http://www.1994july.club/?p=52121
http://www.1994july.club/?p=52026
http://www.1994july.club/?p=51893
http://www.1994july.club/?p=52008
http://www.1994july.club/?p=52054

 

以上是关于SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务的主要内容,如果未能解决你的问题,请参考以下文章

阿里Sentinel整合Zuul网关详解

Spring Cloud 应用程序 - 在 Tomcat 上部署后 zuul 超时

spring cloud gateway的作用(面试)

18.SpringCloud都有哪些组件?

Spring Cloud gateway 网关服务二 断言过滤器

SpringCloudAlibaba 实战