1.搭建权限认证模块
1.1 创建myspringcloud-security模块,用于为服务生产者接口加密
1.2 配置POM依赖
<?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"><parent><artifactId>myspringcloud</artifactId><groupId>com.en</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><version>1.0.0</version><artifactId>myspringcloud-security</artifactId><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies></project>
1.3 父工程添加此依赖
1.4 创建com.en.config路径,创建WebSecurityConfiguration.java配置类,为所有生产者服务接口加密
package com.en.config;import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {@Overridepublic void configure(AuthenticationManagerBuilder auth)throws Exception {auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("root").password(new BCryptPasswordEncoder().encode("root")).roles("USER").and().withUser("admin").password(new BCryptPasswordEncoder().encode("root")).roles("USER", "ADMIN");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.httpBasic().and().authorizeRequests().anyRequest().fullyAuthenticated();http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);}}
1.5 生产者服务导入加密依赖
1.6 服务消费方RestConfig类修改,在Http头信息中加入加密验证信息
package com.en.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;import java.nio.charset.Charset;
import java.util.Base64;@Configuration
public class RestConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}@Beanpublic HttpHeaders getHeaders() {HttpHeaders headers = new HttpHeaders();String auth = "admin:root";byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));String authHeader = "Basic " + new String(encodedAuth);headers.set("Authorization", authHeader);return headers;}}
1.7 服务消费方controller请求修改,调用时在http头中加入验证信息
package com.en.controller;import com.en.po.ProductPo;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
/*** @ClassName ConsumerProductController* @Description 服务消费方控制器* @Author liuxiaobai* @Date 2020年6月26日09:18:41* @Version 1.0**/
@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {private static final String PRODUCT_GET_URL = "http://localhost:8081/prodcut/getInfoById/";private static final String PRODUCT_LIST_URL="http://localhost:8081/prodcut/getAllInfo/";private static final String PRODUCT_ADD_URL = "http://localhost:8081/prodcut/addInfo/";@Resourceprivate RestTemplate restTemplate;@Resourceprivate HttpHeaders httpHeaders;@RequestMapping("/product/getInfoById")public Object getProduct(long id) {return restTemplate.exchange(PRODUCT_GET_URL + id,HttpMethod.GET,new HttpEntity<>(httpHeaders), ProductPo.class).getBody();}@RequestMapping("/product/getAllInfo")public Object listProduct() {return restTemplate.exchange(PRODUCT_LIST_URL,HttpMethod.GET,new HttpEntity<>(httpHeaders), List.class).getBody();}@RequestMapping("/product/addInfo")public Object addPorduct(ProductPo productPo) {return restTemplate.exchange(PRODUCT_ADD_URL, HttpMethod.POST,new HttpEntity<>(productPo,httpHeaders), Boolean.class).getBody();}
}
1.8 重启生产者、消费者服务,浏览器验证接口调用,用户名:admin/root 密码:root/root
调用时提示输入验证信息,输入后生产者服务接口访问正常
消费者服务接口访问正常
2.搭建Eureka注册中心
2.1 新建Eureka服务端
2.2 导入POM依赖
<?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"><parent><artifactId>myspringcloud</artifactId><groupId>com.en</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>myspringcloud-eureka</artifactId><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><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.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies></project>
2.3 修改application.yml,配置eureka相关信息
server:port: 7001
eureka:instance: # eureak实例定义hostname: localhost # 定义 Eureka 实例所在的主机名称
2.4 创建Eureka启动类
package com.en.config;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class,args);}
}
2.5 修改服务生产者配置文件,将服务注册到Eureka
server:port: 8081
mybatis:mapper-locations: # 所有的mapper映射文件- classpath:mapping/*.xml
spring:application:name: myspringcloud-provider-productdatasource:type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=GMT%2B8 # 数据库连接地址username: rootpassword: root
logging:level:com.en.mapper: debug
eureka:client: # 客户端进行Eureka注册的配置service-url:defaultZone: http://localhost:7001/eurekainstance:instance-id: microcloud-provider-productprefer-ip-address: true
info:app.name: myspringcloud-provider-productcompany.name: enbuild.artifactId: $project.artifactId$build.modelVersion: $project.modelVersion$
2.6 服务生产者启动类加入Eureka客户端注解
2.7 加入Eureka详细信息查看功能,修改服务生产者POM引入actuator模块
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
2.8 父工程修改POM
<resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource>
</resources><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><configuration><delimiters><delimiter>$</delimiter></delimiters></configuration>
</plugin>
2.9 启动Eureka服务器,生产者服务注册成功
点进去可以看到详细信息
2.10 现在Eureka已经可以使用了,但启动的时候抱一个连接的错误,修改一下Eureka服务端配置文件
server:port: 7001
eureka:server:eviction-interval-timer-in-ms: 1000 #设置清理的间隔时间,而后这个时间使用的是毫秒单位(默认是60秒)client:fetch-registry: falseregister-with-eureka: falseinstance: # eureak实例定义hostname: localhost # 定义 Eureka 实例所在的主机名称
2.11 还有一个问题就是生产者服务宕机后,Eureka服务端还保留着生产者服务的信息,不久后会触发Eureka安全机制,解决方案为给生产者服务提供一个心跳检测,修改生产者服务配置文件
server:port: 8081
mybatis:mapper-locations: # 所有的mapper映射文件- classpath:mapping/*.xml
spring:application:name: myspringcloud-provider-productdatasource:type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=GMT%2B8 # 数据库连接地址username: rootpassword: root
logging:level:com.en.mapper: debug
eureka:client: # 客户端进行Eureka注册的配置service-url:defaultZone: http://localhost:7001/eurekainstance:instance-id: microcloud-provider-productprefer-ip-address: truelease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)info:app.name: myspringcloud-provider-productcompany.name: enbuild.artifactId: $project.artifactId$build.modelVersion: $project.modelVersion$
2.12 现在用SpringSecurity给Eureka提供一个安全认证,POM文件引入SpringSecurity依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.13 修改Eureka服务端application.yml文件,增加用户、密码验证
server:port: 7001
eureka:server:eviction-interval-timer-in-ms: 1000 #设置清理的间隔时间,而后这个时间使用的是毫秒单位(默认是60秒)client:fetch-registry: falseregister-with-eureka: falseservice-url:defaultZone: http://admin:root@localhost:7001/eurekainstance: # eureak实例定义hostname: localhost # 定义 Eureka 实例所在的主机名称
spring:security:user:name: adminpassword: root
2.14 修改服务生产者application.yml文件,增加验证信息
defaultZone: http://admin:root@localhost:7001/eureka
2.15 在Eureka服务端新增权限配置类,关闭csrf劫持
package com.en.config;import org.springframework.context.annotation.Configuration;
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;@Configuration
@EnableWebSecurity
public class EurekaSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable();super.configure(http);}
}
2.16 重启服务,登录Eureka前端页面,提示输入用户名信息,登入后一切正常
2.17 优化Eureka高可用,配置Eureka集群,拷贝两份Eureka服务端,分别改名为Eureka2和Eureka3
2.18 修改本地hosts文件,新增如下内容
127.0.0.1 eureka
127.0.0.1 eureka2
127.0.0.1 eureka3
2.19 修改Eureka服务端1application.yml配置文件,修改端口以及注册位置,Eureka2和Eureka3同理
server:port: 7001
eureka:server:eviction-interval-timer-in-ms: 1000 #设置清理的间隔时间,而后这个时间使用的是毫秒单位(默认是60秒)client:fetch-registry: falseregister-with-eureka: falseservice-url:defaultZone: http://admin:root@eureka:7001/eureka,http://admin:root@eureka2:7002/eureka,http://admin:root@eureka3:7003/eurekainstance: # eureak实例定义hostname: eureka # 定义 Eureka 实例所在的主机名称
spring:security:user:name: adminpassword: root
2.20 修改服务生产者Eureka注册地址
server:port: 8081
mybatis:mapper-locations: # 所有的mapper映射文件- classpath:mapping/*.xml
spring:application:name: myspringcloud-provider-productdatasource:type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=GMT%2B8 # 数据库连接地址username: rootpassword: root
logging:level:com.en.mapper: debug
eureka:client: # 客户端进行Eureka注册的配置service-url:defaultZone: http://admin:root@eureka:7001/eureka,http://admin:root@eureka2:7002/eureka,http://admin:root@eureka3:7003/eurekainstance:instance-id: microcloud-provider-productprefer-ip-address: truelease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)info:app.name: myspringcloud-provider-productcompany.name: enbuild.artifactId: $project.artifactId$build.modelVersion: $project.modelVersion$
2.21 全部服务重启,Eureka集群已生效,消费方接口调用正常
源码自取:
github地址:https://github.com/L1021204735/myspringcloud2