从零开始搭建微服务:资源服务器

为了演示认证服务器和资源服务器在分离的模式下,如何进行资源保护和资源获取,我们来搭建两个微服务提供者:elsa-server-system和elsa-server-demo资源服务器。
因为存在多个资源服务器,因此,我们为这些微服务提供一个父模块,来统一管理。

elsa-server 父模块

创建elsa-server 父模块项目

File==>新建==>Other==>搜索Maven,选择Maven Module,然后Next
在这里插入图片描述
填写Module Name:elsa-server,点击Next
在这里插入图片描述
在这里插入图片描述
一直Next至FInish为止,创建完成,删除不必要的文件,仅保留pom.xml文件,项目结构如下
在这里插入图片描述

配置elsa-server依赖
<?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>
	<parent>
		<groupId>com.elsa</groupId>
		<artifactId>elsa-cloud</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>
    <artifactId>elsa-server</artifactId>
    <packaging>pom</packaging>
    <name>elsa-server</name>
    <description>Elsa-Server资源服务提供模块</description>
	<dependencies>
		<dependency>
			<groupId>com.elsa</groupId>
			<artifactId>elsa-common</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

值得注意的是:

  • <packaging>pom</packaging> ,因为此项目是作为所有微服务的父项目,所以这里指定为pom
  • 因为是微服务,同样的需要各种依赖,所以引入elsa-common

elsa-server-system 系统模块

创建elsa-server-system系统模块

在项目elsa-server上右键==>新建==>Other==>搜索Maven,选择Maven Module,然后Next
在这里插入图片描述
填写Module Name:elsa-server-system,点击Next
在这里插入图片描述
在这里插入图片描述
一直Next至FInish为止,创建完成,添加资源目录resources,项目结构如下
在这里插入图片描述

引入系统模块依赖
<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.elsa</groupId>
		<artifactId>elsa-server</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>
	<artifactId>elsa-server-system</artifactId>
	<name>elsa-server-system</name>
	<description>Elsa-Server-System微服务系统模块</description>

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

</project>
创建系统模块入口类
@EnableDiscoveryClient
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)	//表示开启Spring Cloud Security权限注解
public class ElsaServerSystemApp {
    public static void main(String[] args) {
        SpringApplication.run(ElsaServerSystemApp.class, args);
    }
}

  • @EnableDiscoveryClient 开启服务注册与发现
  • @EnableGlobalMethodSecurity(prePostEnabled = true) 表示开启Spring Cloud Security权限注解
系统模块application.yml配置
server:
  port: 8201

spring:
  application:
    name: Elsa-Server-System

eureka:
  instance:
    # 向Eureka 服务端发送心跳的间隔时间,单位为秒,用于服务续约。这里配置为20秒,即每隔20秒向febs-register发送心跳,表明当前服务没有宕机
    lease-renewal-interval-in-seconds: 20
  client:
    # 为true时表示将当前服务注册到Eureak服务端
    register-with-eureka: true
    # 为true时表示从Eureka 服务端获取注册的服务信息
    fetch-registry: true
    # 新实例信息的变化到Eureka服务端的间隔时间,单位为秒
    instance-info-replication-interval-seconds: 30
    # 默认值为30秒,即每30秒去Eureka服务端上获取服务并缓存,这里指定为3秒的原因是方便开发时测试,实际可以指定为默认值即可;
    registry-fetch-interval-seconds: 3
    serviceUrl:
      # 指定Eureka服务端地址
      defaultZone: http://elsa:123456@localhost:8001/register/eureka/
      
# oauth2相关配置    
security:
  oauth2:
    resource:
      id: ${spring.application.name}
      user-info-uri: http://localhost:8301/auth/user

配置里内容基本上前面章节中有重复,就不作过多介绍。这里主要说明下:user-info-uri,它的原理是在授权服务器认证后将认证信息Principal通过形参绑定到URL的方式,获取用户信息。

ElsaServerSystemResourceServerConfigure Web安全配置类

配置所有访问elsa-server-system的请求都需要认证,只有通过认证服务器发放的令牌才能进行访问。

@Configuration
@EnableResourceServer
public class ElsaServerSystemResourceServerConfigure extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .requestMatchers().antMatchers("/**")
            .and()
                .authorizeRequests()
                .antMatchers("/**").authenticated();
    }
}

TestController

创建一个Controller,对外提供一些REST服务。在com.elsa.server.system路径下新建controller包,然后在该包下新增TestController:

@RestController
public class TestController {

	@GetMapping("info")
	public String test() {
		return "elsa-server-system";
	}

	@GetMapping("user")
	public Principal currentUser(Principal principal) {
		return principal;
	}
}

elsa-server-demo Demo模块

参照elsa-server-system系统模块创建过程,创建elsa-server子项目,并且引入依赖,创建入口类,配置application.yml,Web安全配置类,过程无差异,可参照源码。唯一不同的是测试controller稍作调整。

DemoController
@RestController
public class DemoController {
	@GetMapping("demo1")
	@PreAuthorize("hasAnyAuthority('user:add')")
	public String demo1() {
		return "拥有'user:add'权限";
	}

	@GetMapping("demo2")
	@PreAuthorize("hasAnyAuthority('user:update')")
	public String demo2() {
		return "拥有'user:update'权限";
	}

	@GetMapping("user")
	public Principal currentUser(Principal principal) {
		return principal;
	}
}

  • demo1方法测试拥有权限user:add的情况。
  • demo2方法测试没有权限user:update的情况。
  • user方法测试获取用户信息,此处主要是针对user-info-uri。

网关服务器配置

到这里,elsa-server-system和elsa-server-demo资源服务器微服务创建完成,下面需要在网关服务器elsa-gateway配置网关访问以上两个资源服务器的路由网关。

zuul:
  routes:
    system:
      path: /system/**
      serviceId: Elsa-Server-System
      sensitiveHeaders: "*"
    demo:
      path: /demo/**
      serviceId: Elsa-Server-Demo
      sensitiveHeaders: "*"  

网关服务器完整配置文件application.xml

server:
  port: 8301

spring:
  application:
    name: Elsa-Gateway

zuul:
  routes:
    auth:
      # 以/auth开头的请求都会被转发到名称为Elsa-Auth的服务上
      path: /auth/**
      # 服务名
      serviceId: Elsa-Auth
      # 由于我们需要在请求头中携带令牌,所以sensitiveHeaders设置为*,表示不过滤请求头信息,即请求的请求头信息将原封不动的转发出去
      sensitiveHeaders: "*"
    system:
      path: /system/**
      serviceId: Elsa-Server-System
      sensitiveHeaders: "*"
    demo:
      path: /demo/**
      serviceId: Elsa-Server-Demo
      sensitiveHeaders: "*"      
  # 设置为true时,表示开启重试机制;
  retryable: true
  # Zuul配合Eureka后会有一套默认的配置规则,这里我们只想请求根据我们显示配置的路由规则走,所以设置为*,表示关闭所有默认路由配置规则;
  ignored-services: "*"
  ribbon:
    eager-load:
      # Zuul内部通过Ribbon按照一定的负载均衡算法来获取服务,Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,第一次请求很容易出现超时的情况。设置为true的时候表示开启Ribbon的饥饿加载模式,即在应用启动的时候就去获取相应的Client备用。
      enabled: true

ribbon:
  # 设置请求超时时间,单位为毫秒;
  ReadTimeout: 3000

eureka:
  instance:
    # 向Eureka 服务端发送心跳的间隔时间,单位为秒,用于服务续约。这里配置为20秒,即每隔20秒向febs-register发送心跳,表明当前服务没有宕机
    lease-renewal-interval-in-seconds: 20
  client:
    # 为true时表示将当前服务注册到Eureak服务端
    register-with-eureka: true
    # 为true时表示从Eureka 服务端获取注册的服务信息
    fetch-registry: true
    # 新实例信息的变化到Eureka服务端的间隔时间,单位为秒
    instance-info-replication-interval-seconds: 30
    # 默认值为30秒,即每30秒去Eureka服务端上获取服务并缓存,这里指定为3秒的原因是方便开发时测试,实际可以指定为默认值即可;
    registry-fetch-interval-seconds: 3
    serviceUrl:
      # 指定Eureka服务端地址
      defaultZone: http://elsa:123456@localhost:8001/register/eureka/

PostMan测试

分别启动应用
1.Redis
2.ElsaRegesterApp
3.ElsaAuthApp
4.ElsaGatewayApp
5.ElsaServerSystemApp
6.ElsaServerDemoApp

资源服务器-认证

在这里插入图片描述
不携带令牌时,失败
在这里插入图片描述
携带令牌时,成功
在这里插入图片描述

资源服务器-系统服务获取用户信息

不携带令牌时,失败
在这里插入图片描述
携带令牌时,成功
在这里插入图片描述

资源服务器-Demo模块服务有权限

在这里插入图片描述
我们在elsa-auth模块的ElsaUserDetailService类loadUserByUsername方法模拟用户拥有user:add权限,所以可以正常访问。
在这里插入图片描述
而下面的demo2没有user:update权限,所以无法访问。

资源服务器-Demo模块服务无权限

在这里插入图片描述
当我们在ElsaUserDetailService类loadUserByUsername方法中增加user:update时,重启ElsaAuthApp。
在这里插入图片描述
再测试此URL时,拥有user:update权限
在这里插入图片描述

资源服务器-Demo模块服务获取用户信息

在这里插入图片描述

源码下载

源码地址:资源服务器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值