虽说只有三步,但服务端和客户端都要配置
1、加依赖:
服务端和客户端,只有最后一个单词不同 server和client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、改配置,在application.properties中
服务端:
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
客户端:
server.port=8899
spring.application.name=resource-server
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
3、加注解
在入口类上分别加:@ENABEEUREKASERVER 和 @ENABLEEUREKACLIENT
4、最后特别说明,如果出现了EUREKA集群,这样配置:
Eureka1项目中配置文件
server.port=8761
spring.application.name=eureka1
eureka.client.service-url.defaultZone=http://localhost:8762/eureka, http://localhost:8763/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
Eureka2项目中配置文件
server.port=8762
spring.application.name=eureka2
eureka.client.service-url.defaultZone=http://localhost:8761/eureka, http://localhost:8763/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
Eureka3项目中配置文件
server.port=8763
spring.application.name=eureka3
eureka.client.service-url.defaultZone=http://localhost:8761/eureka, http://localhost:8762/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
第二部分 ZUUL
1. 依赖
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>straw-commons</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</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-netflix-zuul
</artifactId>
</dependency>
2、properties:
server.port=9000
#给当前实例起名
spring.application.name=gateway
#设置动态路由routes.后面的名字是自己起的
#path指定一个路径,在有请求访问这个路径时开始路由
zuul.routes.resource.path=/resource/**
#routes.跟的名字和上面的配置必须一致
#service-id跟的必须是已经存在的微服务实例名
zuul.routes.resource.service-id=resource-server
//zuul.routes.sys.path=/sys/**
//zuul.routes.sys.service-id=sys-service
//#允许路由传递"敏感头" 即包含登录认证有关信息
//zuul.routes.sys.sensitive-headers=Authorization
//spring.redis.host=localhost
//spring.redis.port=6379
//#将session保存到redis中
///spring.session.store-type=redis
//zuul.routes.faq.path=/faq/**
//zuul.routes.faq.service-id=faq-service
///#允许路由传递"敏感头" 即包含登录认证有关信息
//zuul.routes.faq.sensitive-headers=Authorization
//zuul.routes.search.path=/search/**
///zuul.routes.search.service-id=search-service
//#允许路由传递"敏感头" 即包含登录认证有关信息
//zuul.routes.search.sensitive-headers=Authorization
//eureka.instance.prefer-ip-address=false
//eureka.instance.hostname=localhost
//eureka.instance.ip-address=127.0.0.1
//eureka.instance.instance-id=${spring.application.name}:${eureka.instance.hostname}:${server.port}
3、注解 在启动类上
@ENABLEZUULPROXY
4、Ribbin使用
@SpringBootApplication
@EnableZuulProxy
@EnableRedisHttpSession //允许共享session
public class StrawGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(StrawGatewayApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@Test
void contextLoads() {
String url="http://sys-service/v1/auth/demo";
String str=restTemplate.getForObject(url,String.class);
System.out.println(str);
}
5,使用示例
package cn.tedu.straw.gateway.service;
import cn.tedu.straw.commons.model.Permission;
import cn.tedu.straw.commons.model.Role;
import cn.tedu.straw.commons.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@Component
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {
@Resource
private RestTemplate restTemplate;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1.调用根据用户名获得用户对象的Rest接口
String url="http://sys-service/v1/auth/user?username={1}";
//getForObject方法第三个参数开始是参入url{}中占位符用的
User user=restTemplate.getForObject(url,User.class,username);
log.debug("查询出用户:{}",user);
//2.判断用户不为空
if(user==null){
throw new UsernameNotFoundException("用户名密码错误");
}
//3.调用根据用户id获得用户权限的Rest接口
url="http://sys-service/v1/auth/permissions?userId={1}";
//凡是Rest接口返回List格式的,调用时使用对应泛型的数组类型接收
//原因是传递过程中数据是json格式,json格式是js代码,js代码没有List类型
Permission[] permissions=restTemplate.getForObject(
url,Permission[].class,user.getId());
//4.调用根据用户id获得用户角色的Rest接口
url="http://sys-service/v1/auth/roles?userId={1}";
Role[] roles=restTemplate.getForObject(
url,Role[].class,user.getId());
//5.将权限和角色赋值到auth数组中
if(permissions==null || roles==null){
throw new UsernameNotFoundException("当前用户权限不足");
}
//声明保存所有权限和角色的数据
String[] auth=new String[permissions.length+roles.length];
int i=0;
for(Permission p :permissions){
auth[i++]=p.getName();
}
for(Role r:roles ){
auth[i++]=r.getName();
}
//6.构造UserDetails对象
UserDetails u= org.springframework.security.core.userdetails
.User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities(auth)
.accountLocked(user.getLocked()==1)
.disabled(user.getEnabled()==0)
.build();
//不要忘了返回u!!!!
return u;
}
}