Spring Cloud微服务安全实战_4-5_搭建OAuth2资源服务器
上一篇搭建了一个OAuth2认证服务器,可以生成token,这篇来改造下之前的订单微服务,使其能够认这个token令牌。
本篇针对订单服务要做三件事:
1,要让他知道自己是资源服务器,他知道这件事后,才会在前边加一个过滤器去验令牌(配置@EnableResourceServer 配置类)
2,要让他知道自己是什么资源服务器(配置资源服务器ID)
3,配置去哪里验令牌,怎么验令牌,要带什么信息去验 (配置@EnableWebSecurity 配置TokenServices,配置AuthenticationManager)
搭建资源服务器


++++++++++++++++++资源服务器现有的各个类++++++++++++++++++++++++++++
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.nb.security</groupId>
<artifactId>nb-order-api</artifactId>
<version>0.0.1-SNAPSHOT</version> <properties>
<java.version>1.8</java.version>
</properties> <dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency> </dependencies> </dependencyManagement> <dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--OAuth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency> <!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> </dependencies> <build>
<plugins> <!--指定JDK编译版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 打包跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin> <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
application.yml:
server:
port: 9060
OrderInfo.java :
package com.nb.security.order; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderInfo { private Long productId; }
OrderController:
package com.nb.security.order; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate; @Slf4j
@RestController
@RequestMapping("/orders")
public class OrderController { private RestTemplate restTemplate = new RestTemplate(); @PostMapping
public OrderInfo create(@RequestBody OrderInfo info){
//查询价格
// PriceInfo price = restTemplate.getForObject("http://localhost:9080/prices/"+info.getProductId(),PriceInfo.class);
// log.info("price is "+price.getPrice());
return info;
} @GetMapping
public OrderInfo getInfo(@PathVariable Long id){
log.info("getInfo: id is "+id);
return new OrderInfo(id);
} }
启动类:
package com.nb.security; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class NbOrderApiApplication { public static void main(String[] args) {
SpringApplication.run(NbOrderApiApplication.class, args);
} }
PriceInfo.java (暂时先不用):
package com.nb.security.order; import lombok.Data; import java.math.BigDecimal; @Data
public class PriceInfo { private Long id; private BigDecimal price;
}
++++++++++++++++++资源服务器现有的各个类结束++++++++++++++++++++++++++++
1,在资源服务器pom哩加上 oauth2的依赖:
<!--OAuth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
2,新建资源服务器配置类,继承 ResourceServerConfigurerAdapter

package com.nb.security.resource.server; 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; /**
* 资源服务器
* 配置了@EnableResourceServer ,所有发往nb-order-api的请求,都会去请求头里找token,找不到不让你过
*/
@Configuration
@EnableResourceServer//告诉nb-order-api,你就是资源服务器
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
//配置资源服务器的id,“现在我就是资源服务器order-server!!!”
resources.resourceId("order-server");
} @Override
public void configure(HttpSecurity http) throws Exception {
/**
* 进入nb-order-api的所有请求,哪些要拦截,哪些要放过,在这里配置
*/
http.authorizeRequests()
.antMatchers("/hello")
.permitAll() //放过/haha不拦截
.anyRequest().authenticated();//其余所有请求都拦截
}
}
ResourceServerConfigurerAdapter 有两个方法:

开篇说的1、2、3中的1和2已经完成了,下面做第3件事,怎么验令牌:
新建配置类:

package com.nb.security.resource.server; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; /**
* 怎么验发往本服务的请求头的令牌
* 1,自定义tokenServices ,说明去哪里去验token
* 2,重写authenticationManagerBean()方法,将AuthenticationManager暴露为一个Bean
* 要认证跟用户相关的信息,一般用 AuthenticationManager
*
* 这样配置了后,所有发往nb-order-api的请求,
* 需要验token的时候就会发请求去http://localhost:9090/oauth/check_token验token,获取到token对应的用户信息
*/
@Configuration
@EnableWebSecurity
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter{ /**
* 通过这个Bean,去远程调用认证服务器,验token
* @return
*/
@Bean
public ResourceServerTokenServices tokenServices(){
RemoteTokenServices tokenServices = new RemoteTokenServices();
tokenServices.setClientId("orderService");//在认证服务器配置的,订单服务的clientId
tokenServices.setClientSecret("123456");//在认证服务器配置的,订单服务的ClientSecret
tokenServices.setCheckTokenEndpointUrl("http://localhost:9090/oauth/check_token");
return tokenServices;
} /**
* 要认证跟用户相关的信息,一般用 AuthenticationManager
* 覆盖这个方法,可以将AuthenticationManager暴露为一个Bean
*
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager authenticationManager = new OAuth2AuthenticationManager();
authenticationManager.setTokenServices(tokenServices());//设置为自定义的TokenServices,去校验令牌
return authenticationManager;
}
}
认证服务器关于订单服务的配置:

启动认证服务器,
启动订单 资源服务器,
访问认证服务器获取token : localhost:9090/oauth/token


拿着 token 去资源服务器创建订单,注意,选择bearer类型的token,生成的请求头是这样的(注:Authorization的value值,postman生成的是以Bearer开头的,但是我看谷歌浏览器restclient插件生成的是bearer的B是小写):


在资源服务器里,可以通过该注解获取用户名:

错误的情况:
如果把资源服务器配置的resourceId改成了order-server222,请求创建订单,会受到如下的错误

如果资源服务器检验token的cilentID获取clientSecret写错了,后台会报错:

++++++++++++++++++++++分割线++++++++++++++++++++++
小结:
接上篇的认证服务器,本篇实现了资源服务器,以及与认证服务器的交互,怎么去验令牌。
遗留疑问:
认证服务器里面,配置资源服务器secret的时候,用passwordEncoder对123456进行了加密,而在资源服务器里,clientSecret确实明文的123456,这两者不需要一致么?
认证服务器里对资源服务器ClientId、 ClientSecret配置:

资源服务器验令牌携带的ClientId、 ClientSecret:

代码github :https://github.com/lhy1234/springcloud-security/tree/chapt-4-5-resource-server
Spring Cloud微服务安全实战_4-5_搭建OAuth2资源服务器的更多相关文章
- Spring cloud微服务安全实战-7-3prometheus环境搭建
Prmetheus 主要用来做来Metrics的监控和报警,这张图是官方的架构图. 这是他的核心 它的作用是根据我们的配置去完成数据的采集.服务的发现,以及数据的存储. 这是服务的发现,通过Servi ...
- Spring cloud微服务安全实战_汇总
Spring cloud微服务安全实战 https://coding.imooc.com/class/chapter/379.html#Anchor Spring Cloud微服务安全实战-1-1 课 ...
- 《Spring Cloud微服务 入门 实战与进阶》
很少在周末发文,还是由于昨晚刚收到实体书,还是耐不住性子马上发文了. 一年前,耗时半年多的时间,写出了我的第一本书<Spring Cloud微服务-全栈技术与案例解析>. 时至今日,一年的 ...
- Spring Cloud微服务安全实战_00_前言
一.前言: 一直以来对服务安全都很感兴趣,所以就学习.这是学习immoc的 jojo老师的 <Spring Cloud微服务安全实战课程>的笔记,讲的很好. 课程简介: 二.最终形成的架 ...
- Spring cloud微服务安全实战 最新完整教程
课程资料获取链接:点击这里 采用流行的微服务架构开发,应用程序访问安全将会面临更多更复杂的挑战,尤其是开发者最关心的三大问题:认证授权.可用性.可视化.本课程从简单的API安全入手,过渡到复杂的微服务 ...
- Spring Cloud微服务安全实战_4-3_订单微服务&价格微服务
实现一个场景: 订单微服务: POM: <?xml version="1.0" encoding="UTF-8"?> <project xml ...
- Spring Cloud微服务安全实战_4-4_OAuth2协议与微服务安全
接上篇文章,在这个流程中,PostMan可以代表客户端应用,订单服务是资源服务器,唯一缺少的是 认证服务器 ,下面来搭建认证服务器 项目结构: Pom.xml : DependencyManager ...
- Spring cloud微服务安全实战-6-8sentinel限流实战
阿里2018年开源的. 简单来说就是干三件事,最终的结果就是保证你的服务可用,不会崩掉.保证服务高可用. 流控 先从最简单的场景来入手. 1.引用一个依赖, 2,声明一个资源. 3.声明一个规则 注意 ...
- Spring cloud微服务安全实战-6-4权限控制改造
授权,权限的控制 令牌里的scope包含fly就有权限访问.根据Oauth的scope来做权限控制, 要让@PreAuthorize生效,就要在启动类里面写一个注解. 里面有一个属性叫做,就是在方法的 ...
随机推荐
- FAQ简介
FAQ:问答系统,Frequently Asked Questions 常见问答系统: FAQ是英文Frequently Asked Questions的缩写,中文意思就是“经常问到的问题”,或者更通 ...
- android shape图形优化Button效果
android shape可以让我们通过定义xml文件的方式创建图形,当然只能实现一些比较简单的图形(圆形,矩形,椭圆,线段),但是已经相当不错了,通过shape创建的图形作为控件的背景已经基本可以满 ...
- HTML连载40-盒子宽度和高度的练习、box-sizing属性
一.判断方法 1.判断是否元素宽高为200的盒子 只需要看:边框+内边距+内容宽度/内容高度的值是否等于200 2.判断是否内容宽高为100的盒子 只需要看:width和heght的值是否等于100 ...
- 【转】在cmd/bat脚本中获取当前脚本文件所在目录
一.关于cd的/d参数 关于cd 的/d参数,在cmd中敲入cd /?可以看到/d参数的解释如下: 使用 /D 命令行开关,除了改变驱动器的当前目录之外,还可改变当前驱动器.这句话不太好理解,我做个试 ...
- Unity Shader NPR 卡通渲染
卡通渲染的主要原理包含两个方面: 1.轮廓线的描边效果 2.模型漫反射离散和纯色高光区域的模拟 描边: 描边的实现方法采用将模型的轮廓线顶点向法线(或顶点)的方向扩展一定的像素得到.也可通过边缘检测( ...
- hue框架介绍和安装部署
大家好,我是来自内蒙古的小哥,我现在在北京学习大数据,我想把学到的东西分享给大家,想和大家一起学习 hue框架介绍和安装部署 hue全称:HUE=Hadoop User Experience 他是cl ...
- vue 上传进度显示
参考资料: https://ask.csdn.net/questions/767017 https://www.cnblogs.com/best-fyx/p/11363506.html 我使用的是el ...
- mssql like 优化
SqlServer中like 的查询一般我们都不推荐,但是当数据库某个字段的值是用分隔符区分的多个链接字符,比如,12,11,23等这样的类型.可能我们需要判断是否包含12. 这个时候我们想到的当然是 ...
- 什么是LNMP架构
LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写.L指Linux,N指Nginx,M一般指MySQL,也可以指MariaDB,P一般指PHP,也可以指Perl或Python ...
- win10自动休眠解决方法
win10使用外接显示器时,总是过2分钟自动睡眠. 这是系统无人值守时睡眠时间的设定,默认是两分钟. 解决方法: 1.运行注册表管理器,win+r ,输入regedit.exe 2.定位到HKEY_L ...