当前位置:网站首页>OAuth2:资源服务器
OAuth2:资源服务器
2022-07-31 14:05:00 【Leon_Jinhai_Sun】
基于@EnableResourceServer实现
前面我们讲解了将我们的服务作为单点登陆应用直接实现单点登陆,那么现在我们如果是以第三方应用进行访问呢?这时我们就需要将我们的服务作为资源服务了,作为资源服务就不会再提供验证的过程,而是直接要求请求时携带Token,而验证过程我们这里就继续用Postman来完成,这才是我们常见的模式。
一句话来说,跟上面相比,我们只需要携带Token就能访问这些资源服务器了,客户端被独立了出来,用于携带Token去访问这些服务。
我们也只需要添加一个注解和少量配置即可:
@EnableResourceServer
@SpringBootApplication
public class BookApplication {
public static void main(String[] args) {
SpringApplication.run(BookApplication.class, args);
}
}配置中只需要:
security:
oauth2:
client:
#基操
client-id: web
client-secret: 654321
resource:
#因为资源服务器得验证你的Token是否有访问此资源的权限以及用户信息,所以只需要一个验证地址
token-info-uri: http://localhost:8500/sso/oauth/check_token配置完成后,我们启动服务器,直接访问会发现:

这是由于我们的请求头中没有携带Token信息,现在有两种方式可以访问此资源:
- 在URL后面添加
access_token请求参数,值为Token值
- 在请求头中添加
Authorization,值为Bearer +Token值
我们先来试试看最简的一种:

另一种我们需要使用Postman来完成:

添加验证信息后,会帮助我们转换成请求头信息:


这样我们就将资源服务器搭建完成了。
我们接着来看如何对资源服务器进行深度自定义,我们可以为其编写一个配置类,比如我们现在希望用户授权了某个Scope才可以访问此服务:
@Configuration
public class ResourceConfiguration extends ResourceServerConfigurerAdapter { //继承此类进行高度自定义
@Override
public void configure(HttpSecurity http) throws Exception { //这里也有HttpSecurity对象,方便我们配置SpringSecurity
http
.authorizeRequests()
.anyRequest().access("#oauth2.hasScope('lbwnb')"); //添加自定义规则
//Token必须要有我们自定义scope授权才可以访问此资源
}
}可以看到当没有对应的scope授权时,那么会直接返回insufficient_scope错误:

不知道各位是否有发现,实际上资源服务器完全没有必要将Security的信息保存在Session中了,因为现在只需要将Token告诉资源服务器,那么资源服务器就可以联系验证服务器,得到用户信息,就不需要使用之前的Session存储机制了,所以你会发现HttpSession中没有SPRING_SECURITY_CONTEXT,现在Security信息都是通过连接资源服务器获取。
接着我们将所有的服务都
但是还有一个问题没有解决,我们在使用RestTemplate进行服务间的远程调用时,会得到以下错误:

实际上这是因为在服务调用时没有携带Token信息,我们得想个办法把用户传来的Token信息在进行远程调用时也携带上,因此,我们可以直接使用OAuth2RestTemplate,它会在请求其他服务时携带当前请求的Token信息。它继承自RestTemplate,这里我们直接定义一个Bean:
@Configuration
public class WebConfiguration {
@Resource
OAuth2ClientContext context;
@Bean
public OAuth2RestTemplate restTemplate(){
return new OAuth2RestTemplate(new ClientCredentialsResourceDetails(), context);
}
}接着我们直接替换掉之前的RestTemplate即可:
@Service
public class BorrowServiceImpl implements BorrowService {
@Resource
BorrowMapper mapper;
@Resource
OAuth2RestTemplate template;
@Override
public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
List<Borrow> borrow = mapper.getBorrowsByUid(uid);
User user = template.getForObject("http://localhost:8101/user/"+uid, User.class);
//获取每一本书的详细信息
List<Book> bookList = borrow
.stream()
.map(b -> template.getForObject("http://localhost:8201/book/"+b.getBid(), Book.class))
.collect(Collectors.toList());
return new UserBorrowDetail(user, bookList);
}
}可以看到服务成功调用了:

现在我们来将Nacos加入,并通过Feign实现远程调用。
依赖还是贴一下,不然找不到:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency><dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>所有服务都已经注册成功了:

接着我们配置一下借阅服务的负载均衡:
@Configuration
public class WebConfiguration {
@Resource
OAuth2ClientContext context;
@LoadBalanced //和RestTemplate一样直接添加注解就行了
@Bean
public OAuth2RestTemplate restTemplate(){
return new OAuth2RestTemplate(new ClientCredentialsResourceDetails(), context);
}
}
现在我们来把它替换为Feign,老样子,两个客户端:
@FeignClient("user-service")
public interface UserClient {
@RequestMapping("/user/{uid}")
User getUserById(@PathVariable("uid") int uid);
}@FeignClient("book-service")
public interface BookClient {
@RequestMapping("/book/{bid}")
Book getBookById(@PathVariable("bid") int bid);
}但是配置完成之后,又出现刚刚的问题了,OpenFeign也没有携带Token进行访问:

那么怎么配置Feign携带Token访问呢?遇到这种问题直接去官方查:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#oauth2-support,非常简单,两个配置就搞定:
feign:
oauth2:
#开启Oauth支持,这样就会在请求头中携带Token了
enabled: true
#同时开启负载均衡支持
load-balanced: true重启服务器,可以看到结果OK了:

这样我们就成功将之前的三个服务作为资源服务器了,注意和我们上面的作为客户端是不同的,将服务直接作为客户端相当于只需要验证通过即可,并且还是要保存Session信息,相当于只是将登录流程换到统一的验证服务器上进行罢了。而将其作为资源服务器,那么就需要另外找客户端(可以是浏览器、小程序、App、第三方服务等)来访问,并且也是需要先进行验证然后再通过携带Token进行访问,这种模式是我们比较常见的模式。
边栏推荐
- leetcode:2032. 至少在两个数组中出现的值
- leetcode:2032. Values that appear in at least two arrays
- 文本相似度计算(中英文)详解实战
- Resnet&API
- 搭建私有的的Nuget包服务器教程
- Sliding window method to segment data
- Motion capture system for end-positioning control of flexible manipulators
- C# using ComboBox control
- “听我说谢谢你”还能用古诗来说?清华搞了个“据意查句”神器,一键搜索你想要的名言警句...
- 代码随想录笔记_哈希_454四数相加II
猜你喜欢

「面经分享」西北大学 | 字节 生活服务 | 一面二面三面 HR 面

MySQL 23道经典面试吊打面试官

Resolved (pymysqL connect to the database error) pymysqL. Err. ProgrammingError: (1146, "Table" test. Students' doesn 't exist ")

The batch size does not have to be a power of 2!The latest conclusions of senior ML scholars

技能大赛dhcp服务训练题
![Miller_Rabin Miller Rabin probability sieve [template]](/img/51/8dcc9f78478debf7d3dcfa6d1a23e3.png)
Miller_Rabin Miller Rabin probability sieve [template]

C#高级--委托
![[Blue Bridge Cup Trial Question 46] Scratch Magnet Game Children's Programming Scratch Blue Bridge Cup Trial Question Explanation](/img/57/f23c21c7ed4b9701a3f6119bfd8493.png)
[Blue Bridge Cup Trial Question 46] Scratch Magnet Game Children's Programming Scratch Blue Bridge Cup Trial Question Explanation

技能大赛训练题:ftp 服务攻防与加固

A detailed explanation of the usage of Async and Await in C#
随机推荐
IDEA can't find the Database solution
Shell script classic case: detecting whether a batch of hosts is alive
LeetCode·每日一题·1161.最大层内元素和·层次遍历
我把问烂了的MySQL面试题总结了一下
A detailed explanation of the usage of Async and Await in C#
Shell project combat 1. System performance analysis
[QNX Hypervisor 2.2 User Manual]9.14 safety
[QNX Hypervisor 2.2 User Manual] 9.13 rom
Numbers that appear only once in LeetCode
新款现代帕里斯帝预售开启,安全、舒适一个不落
1小时直播招募令:行业大咖干货分享,企业报名开启丨量子位·视点
pytorch gpu版本安装最新
49.【拷贝构造函数与重载】
C# using ComboBox control
MySQL 23 classic interviews hang the interviewer
[QNX Hypervisor 2.2用户手册]9.14 safety
I summed up the bad MySQL interview questions
Open Inventor 10.12 Major Improvements - Harmony Edition
numpy矩阵和向量的保存与加载,以及使用保存的向量进行相似度计算
纸质说明书秒变3D动画,斯坦福大学吴佳俊最新研究,入选ECCV 2022