springcolud demo(亲自搭建)

创建 一个简单的demo。整合几个基本的组件:
注册中心:Spring Cloud Netflix
配置中心:Spring Cloud Config
鉴权中心:Spring Cloud OAuth2
hystrix、feign、Zuul、Eureka等。
所有工程的都事项了负载。
写作不容易,盗版必究
总的依赖控制 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wxd.springcloud</groupId>
    <artifactId>spring-cloud-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>cloud-register</module>
        <module>cloud-producer</module>
        <module>cloud-consumer</module>
        <module>cloud-gateway</module>
        <module>cloud-config-server</module>
        <module>cloud-config-client</module>
        <module>cloud-OAuth2-server</module>
        <module>cloud-OAuth2-client</module>
    </modules>
    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
        <project.reporting.outputencoding>UTF-8</project.reporting.outputencoding>
        <java.version>1.8</java.version>
        <swagger.version>2.6.0</swagger.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
</project>

一 创建注册中心

  1. 访问注册中心的地址 http://localhost:8081/
    如图:demo.jpg
    在这里插入图片描述
  2. pom
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
  1. yml

    server:
      port: 8081
    spring:
      application:
        name: eureka-server
    eureka:
      client:
        # 表示是否将自己注册到Eureka Server,默认为true。
        registerWithEureka: false
        # 表示是否从Eureka Server获取注册信息,默认为true。
        fetchRegistry: false
        # 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka ;多个地址可使用,分隔
        serviceUrl:
          defaultZone: http://localhost:${server.port}/eureka/
  1. 启动类
    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class RegisterApp {
        public static void main(String[] args) {
            SpringApplication.run(RegisterApp.class, args);
        }
    }
    
  2. 集群搭建参考
    https://blog.csdn.net/maoyeqiu/article/details/78554196
    主要配置如下
     
     #server1
     spring.application.name=eureka-server
     server.port=8095
     eureka.instance.hostname=127.0.0.1:8095
     eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8096/eureka/,http://127.0.0.1:8097/eureka/
      
     #server2
     spring.application.name=eureka-server
     server.port=8096
     eureka.instance.hostname=127.0.0.1:8096
     eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8095/eureka/,http://127.0.0.1:8097/eureka/
      
     #server3
     spring.application.name=eureka-server
     server.port=8097
     eureka.instance.hostname=127.0.0.1:8097
     eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8095/eureka/,http://127.0.0.1:8096/eureka/
    
    

二. 创建服务端
###服务端

  1. pom
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
  2. yml
    server:
      port: 8082
    spring:
      application:
        name: producer-server
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    
  3. 启动类
    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProducerApp {
        public static void main(String[] args) {
            SpringApplication.run(ProducerApp.class, args);
        }
    }
    
    
  4. 创建UserController
    package com.wxd.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
        @Value("${server.port}")
        private String port;
    
        @GetMapping("/get")
        public String getPort() {
            return "Producer Server port: " + port;
        }
    
    }
    
    

这里只是简单的写一个服务。集成数据库等自己完成。
访问接口如下图

在这里插入图片描述

三. 创建客户端
###消费端

  1. pom

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    
  2. yml

    server:
      port: 8083
    spring:
      application:
        name: consumer-server
    eureka:
      client:
        serviceUrl:
          #注册中心地址 多个用逗号隔开
          defaultZone: http://localhost:8081/eureka/
    #开启断路器
    feign:
      hystrix:
        enabled: true
    
  3. 启动类

    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @EnableDiscoveryClient//注册中心
    @EnableFeignClients//开启feign 声明式REST, 里面包括Hystrix 断路器
    @SpringBootApplication
    @EnableCircuitBreaker//开启Hystrix 断路器
    public class ConsumerApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    }
    
    
  4. 创建RestTemplate

    package com.wxd.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class MyConfiguration {
    
        @LoadBalanced//使用负载
        @Bean
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
  5. 创建UserHystrix
    测试Hystrix

    package com.wxd.service;
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.stereotype.Component;
    
    /**
     * 测试Hystrix
     */
    @Component
    public class UserHystrix {
    
        @HystrixCommand(fallbackMethod = "defaultGetPort2")
        public String getPort2(){
            throw new RuntimeException("");
        }
    
        public String defaultGetPort2(){
            return "服务错误";
        }
    }
    
  6. 创建 UserService
    测试调用服务 及 Hystrix回退

    package com.wxd.service;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Component
    @FeignClient(value = "producer-server", fallback = UserServiceHystrix.class)
    public interface UserService {
        @GetMapping("/get")
        String getPort();
    
    
        @GetMapping("/get1")
    //    @HystrixCommand(fallbackMethod = "defaultGetPort2") 和 @FeignClient不能一起使用
        String getPort2();
    
        default String defaultGetPort2(){
            return "服务错误";
        }
    }
    
  7. 创建 UserServiceHystrix

    package com.wxd.service;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class UserServiceHystrix implements UserService {
        @Override
        public String getPort() {
            return "Producer Server 的服务调用失败";
        }
    
        @Override
        public String getPort2() {
            return "服务错误2";
        }
    }
    
  8. 创建UserController

    package com.wxd.controller;
    
    import com.wxd.service.UserHystrix;
    import com.wxd.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
        @Autowired
        private RestTemplate restTemplate;
        @Autowired
        private UserHystrix userHystrix;
    
        @GetMapping("/get")
        public String getPort() {
            return "consumer get Producer Server port: " + userService.getPort();
        }
    
        @GetMapping("/get3")
        public String getPort3() {
            return "consumer get Producer Server port: " + userService.getPort2();
        }
    
        @GetMapping("/get2")
        public String getPort2() {
            return "consumer get2 Producer Server port: " + restTemplate.getForObject("http://producer-server/get",String.class);
        }
    }
    

    结果如下:
    在这里插入图片描述
    四. 创建 zuul
    ###网关zuul

  9. pom

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    
  10. 启动类

    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    @SpringBootApplication
    @EnableZuulProxy //启动网关路由
    public class ZuulApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ZuulApp.class,args);
        }
    }
    
    
  11. yml

    简单实现

    注意:首先要有注册中心eureka-server和cloud-producer模块

    spring:
      application:
        name: cloud-gateway-zuul
    
    server:
      port: 8808
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    

    直接访问
    http://localhost:8084/producer-server/get 或者
    http://localhost:8084/zuul/producer-server/get
    就可以直接路由到producer-server/get

    配置映射 Zuul指定path和serviceId

    zuul:
      ignoredServices: '*'#忽略所有的服务
      routes:
        producer-server:  # producer-server只是一个标识,保证唯一即可
          path: /pro/** # 映射的路径
          serviceId: producer-server    # 服务id 必须注册服务
          url: http://localhost:8082/ #可以是url 和 serviceId 二选一
    

    访问路径
    http://localhost:8084/pro/get
    五. 创建config-server
    ###config-server

  12. pom

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
    <!--表示为web工程-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!--暴露各种指标  貌似是必须的  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  13. yml

    server:
      port: 8085
    spring:
      application:
        name: config-server
      cloud:
        config:
          server:
            git:
              uri: http://192.168.10.206/wxd/config.git#githttp地址
              search-paths: prducer/*#git下的文件夹,可以写多个和使用*
              username: wxd
              password: 12345678
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/#注册中心实现高可用
    
    
  14. 启动类

    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    @SpringBootApplication
    @EnableConfigServer//开启config服务
    public class ConfigServerApp {
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApp.class, args);
        }
    }
    
    
  15. 准备工作在自己的github创建一个项目
    我这里在项目中新建一个prducer文件夹,在这个文件夹下新建文件config-client-dev.properties内容:

    dburl=http://loachost/1111111111111111
    
  16. 访问路径
    http://localhost:8085/config-client/dev
    在这里插入图片描述
    http://localhost:8085/config-client-dev.properties
    在这里插入图片描述

实现高可用需要部署多台服务器

六. 创建config-client
###config-client

  1. pom
    <!--Spring Cloud Config 客户端依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <!--Spring Boot Actuator,感应服务端变化-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
  2. yml
    server:
      port: 8086
    spring:
      application:
        name: config-client#名字必须和配置文件名字相同config-client-dev.properties
      cloud:
        config:
          profile: dev
          label: master
    #      uri: http://localhost:8085/  #单节点模式
          discovery:#负载模式 如果是负载模式,必须注册到注册中心
            enabled: true
            service-id: config-server
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    management:
      security:
        #SpringBoot 1.5.X 以上默认开通了安全认证,如果不关闭会要求权限
        enabled: false
      endpoints:
        web:
          exposure:
            include: health, info, refresh #暴露接口,实现半自动化刷新
    
    

    关键:这里是bootstrap.yml不是application.yml 因为bootstrap.yml优先级高

  3. 启动类
    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class ConfigClientApp {
        public static void main(String[] args) {
            SpringApplication.run(ConfigClientApp.class, args);
        }
    }
    
    
  4. Controller
    package com.wxd.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RefreshScope //开启更新功能
    @RequestMapping("api")
    public class ConfigController {
    
        @Value("${dburl:asd}")
        private String fromValue;
    
        /**
         * 返回配置文件中的值
         */
        @GetMapping("/from")
        @ResponseBody
        public String returnFormValue(){
            return fromValue;
        }
    }
    
    
  5. 测试

不能实现动态刷新,需要手动刷新。需要优化

七. 创建OAth2-server

OAth2-server 认证与授权服务

  1. pom
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-security</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- 开启负载使用时,需要注册到服务中心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. yml
    server:
      port: 8087
    spring:
      application:
        name: cloud-OAuth2-server
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    
  3. 启动类
    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    
    @SpringBootApplication
    @EnableResourceServer//开启资源服务,因为程序需要对外暴露获取token的API接口
    public class OAuth2ServerApp {
    
        public static void main(String[] args) {
            SpringApplication.run(OAuth2ServerApp.class, args);
        }
    
    }
    
    
  4. 创建AuthorizationServerConfig

    开启授权服务的功能

    package com.wxd.config;
    
    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.crypto.bcrypt.BCryptPasswordEncoder;
    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;
    
    @Configuration
    @EnableAuthorizationServer //开启授权服务的功能
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        AuthenticationManager authenticationManager;
    
        
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            String finalSecret =  new BCryptPasswordEncoder().encode("123456");
            //ClientDetailsServiceConfigurer配置了客户端的一些基本信息
            clients.inMemory() // //将客户端的信息存储在内存中
                    .withClient("client") // client_id /创建了一个client名为browser的客户端
                    .secret(finalSecret) // client_secret
                    .authorizedGrantTypes(/*"implicit",*/"password", "refresh_token") // 该client允许的授权类型
                    .scopes("app"); // 允许的授权范围
        }
    
        /**
         * 设置管理器
         * @param endpoints
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints//.tokenStore(new MyRedisTokenStore(redisConnectionFactory))//Token的存储方式为内存
                    .authenticationManager(authenticationManager)//WebSecurity配置好的
    //                .userDetailsService(userServiceDetail);//读取用户的验证信息 
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            // 允许表单认证
            security.allowFormAuthenticationForClients();
        }
    
    //    @Override
    //    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    //        //配置获取Token的策略
    //        oauthServer
    //                .tokenKeyAccess("permitAll()") //对获取Token的请求不再拦截
    //                .checkTokenAccess("isAuthenticated()"); //验证获取Token的验证信息
    //
    //    }
    
    }
    
    
  5. 创建ResourceServerConfig

    由于 auth-service 需要对外暴露检查 Token 的API接口,所以 auth-service 也是一个资源服务,需要在工程中引入 Spring Security,并做相关配置,对 auth-service 资源进行保护。

    package com.wxd.config;
    
    import org.springframework.context.annotation.Configuration;
    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;
    import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
    
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.
                    csrf().disable()
                    .authorizeRequests().anyRequest().authenticated()
                    .and()
                    .httpBasic();
        }
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            super.configure(resources);
        }
    
    }
    
    
  6. 创建WebSecurityConfig
    package com.wxd.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.userdetails.User;
    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.provisioning.InMemoryUserDetailsManager;
    
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    //    @Autowired
    //    private UserDetailsServiceImpl userDetailsService;
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        /**
         * 创建两个简单的用户用户测试
         *
         * 也可以自己实现
         * @return
         */
        @Bean
        @Override
        protected UserDetailsService userDetailsService() {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    
            String finalPassword = bCryptPasswordEncoder.encode("123456");
            InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
            manager.createUser(User.withUsername("user_1").password(finalPassword).authorities("USER").build());
            manager.createUser(User.withUsername("user_2").password(finalPassword).authorities("USER").build());
    
            return manager;
        }
    
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService())
                    .passwordEncoder(passwordEncoder());
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.requestMatchers().anyRequest()
                    .and()
                    .authorizeRequests()
                    .antMatchers("/oauth/**").permitAll();
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/favor.ioc");
        }
    }
    
    
    获取token如图:

    http://localhost:8087/oauth/token?username=user_1&password=123456&grant_type=password&scope=app&client_id=client&client_secret=123456在这里插入图片描述

  7. 创建UserController

    本例采用 RemoteTokenService 这种方式对 Token 进行验证。如果其他资源服务需要验证 Token,则需要远程调用授权服务暴露的验证 Token 的API接口。

    package com.wxd.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.security.Principal;
    
    /**
     * <p>必须要有,做验证</p>
     * Created by Mr.Yangxiufeng on 2017/12/29.
     * Time:10:43
     * ProjectName:Mirco-Service-Skeleton
     */
    @RestController
    public class UserController {
    
        //暴露Remote Token Services接口
        //如果其它服务需要验证Token,则需要远程调用授权服务暴露的验证Token的API接口
        @RequestMapping("/user")
        public Principal user(Principal user) {
            return user;
        }
    }
    
    

这里只是简单的写一个服务。用户权限等需要自己实现。

八.创建需要鉴权的服务
###鉴权服务

  1. pom
    <!-- 开启负载-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-security</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. yml
    server:
      port: 8088
    spring:
      application:
        name: cloud-OAuth2-client
    #单点测试
    #security:
    #  oauth2:
    #    client:
    #      accessTokenUri: http://localhost:8087/oauth/token
    #      userAuthorizationUri: http://localhost:8087/oauth/authorize
    #      clientId: client
    #      clientSecret: 123456
    #      grantType: client_credentials,password
    #      scope: app
    #    resource:
    #      userInfoUri: http://localhost:8087/user
    #负载 使用服务调用的方式。    
    security:
      oauth2:
        client:
          accessTokenUri: http://cloud-OAuth2-server/oauth/token
          userAuthorizationUri: http://cloud-OAuth2-server/oauth/authorize
          clientId: client
          clientSecret: 123456
          grantType: client_credentials,password
          scope: app
        resource:
          userInfoUri: http://cloud-OAuth2-server/user
          loadBalanced: true
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    
  3. 启动类
    package com.wxd;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class OAuth2ClientApp {
    
        public static void main(String[] args) {
            SpringApplication.run(OAuth2ClientApp.class, args);
        }
    
    
    }
    
    
  4. 创建OAuth2ClientConfig
    package com.wxd.config;
    
    import feign.RequestInterceptor;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
    import org.springframework.security.oauth2.client.OAuth2RestTemplate;
    import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
    import org.springframework.web.client.RestTemplate;
    
    @EnableOAuth2Client
    @EnableConfigurationProperties
    @Configuration
    public class OAuth2ClientConfig {
    
        @Bean
        @ConfigurationProperties(prefix = "security.oauth2.client")//获取Bean的配置属性
        public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
            //配置受保护资源的信息
            return new ClientCredentialsResourceDetails();
        }
    
        @Bean
        public RequestInterceptor oauth2FeignRequestInterceptor() {
            //配置一个过滤器,存储当前请求和上下文
            //在request域内创建 AccessTokenRequest 类型的Bean。
            return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());
        }
    
        @Bean
        public OAuth2RestTemplate clientCredentialsRestTemplate() {
            //向认证中心服务请求的
            return new OAuth2RestTemplate(clientCredentialsResourceDetails());
        }
    
    }
    
  5. 创建ResourceServerConfiguration
    package com.wxd.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    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
    @EnableGlobalMethodSecurity(prePostEnabled = true)//注解开启在方法上的保护功能
    public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/order/**").authenticated(); // 配置order访问控制,必须认证后才可以访问
        }
    
    }
    
    
  6. 创建OAuth2Controller
    package com.wxd.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.oauth2.provider.OAuth2Authentication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.security.Principal;
    
    @RestController
    public class OAuth2Controller {
        Logger logger = LoggerFactory.getLogger(OAuth2Controller.class);
        @GetMapping("/person")
        @PreAuthorize("hasAuthority('USER1')")//需要ROLE_ADMIN权限
        public @ResponseBody
        Object personInfo() {
            return "{ad:asd}";
        }
    
        @GetMapping("/product/{id}")
        public String getProduct(@PathVariable String id) {
            return "product id : " + id;
        }
    
        @GetMapping("/order/{id}")//不需要任何权限,只要Header中的Token正确即可
        public String getOrder(@PathVariable String id) {
            return "order id : " + id;
        }
    
        //获取当前“Token”用户信息 token是入参
        @GetMapping("/getPrinciple")
        public OAuth2Authentication getPrinciple(OAuth2Authentication oAuth2Authentication, Principal principal, Authentication authentication) {
            logger.info(oAuth2Authentication.getUserAuthentication().getAuthorities().toString());
            logger.info(oAuth2Authentication.toString());
            logger.info("principal.toString() " + principal.toString());
            logger.info("principal.getName() " + principal.getName());
            logger.info("authentication: " + authentication.getAuthorities().toString());
    
            return oAuth2Authentication;
        }
    }
    
    

    http://localhost:8088/getPrinciple?access_token=ff71fcb6-5963-4c2e-9438-8704ce93824c
    在这里插入图片描述
    http://localhost:8088/order/1?access_token=1cab1803-8b0d-4a3e-818a-52434d18a23e
    在这里插入图片描述

这里只是简单的写一个服务。集成数据库等自己完成。

总的项目结构如图:
在这里插入图片描述
重点源码下载地址 https://download.csdn.net/download/qq_25451199/10992152

如果对你有帮助可以请作者喝一杯咖啡:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一套用于构建分布式系统的开发工具集合,它基于Spring框架,提供了一系列开箱即用的分布式系统的解决方案。Spring Cloud Demo是一个演示示例,用于展示Spring Cloud的各种功能和使用方式。 Spring Cloud Demo可以帮助开发人员快速了解和掌握Spring Cloud的各种组件和功能。它包含了各种常见的分布式系统组件,如服务注册与发现、负载均衡、服务调用、熔断、服务容错、配置中心等。通过阅读和运行Spring Cloud Demo,开发人员可以学习到如何使用这些组件来构建高可用、可伸缩、可扩展的分布式系统。 以服务注册与发现为例,Spring Cloud Demo中可能包含一个服务注册中心和若干个服务提供者和服务消费者。通过在服务提供者上注册服务,并在服务消费者上发现服务,实现了服务的自动注册与发现。开发人员可以通过运行这个Demo,了解和学习如何使用Spring Cloud提供的服务注册与发现功能。 在Spring Cloud Demo中,还可能包含其他的组件和功能,如负载均衡、熔断、服务容错、配置中心等。开发人员可以通过运行这些示例,深入了解和掌握Spring Cloud提供的各种功能,并在实际项目中应用它们。 总之,Spring Cloud Demo是一个用于展示Spring Cloud各种功能和使用方式的示例,通过阅读和运行这个示例,开发人员可以了解和学习如何使用Spring Cloud构建分布式系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值