当前位置: 首页>編程日記>正文

OAuth2:资源服务器

OAuth2:资源服务器

基于@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: webclient-secret: 654321resource:#因为资源服务器得验证你的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 { //继承此类进行高度自定义@Overridepublic void configure(HttpSecurity http) throws Exception {  //这里也有HttpSecurity对象,方便我们配置SpringSecurityhttp.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 {@ResourceOAuth2ClientContext context;@Beanpublic OAuth2RestTemplate restTemplate(){return new OAuth2RestTemplate(new ClientCredentialsResourceDetails(), context);}
}

接着我们直接替换掉之前的RestTemplate即可:

@Service
public class BorrowServiceImpl implements BorrowService {@ResourceBorrowMapper mapper;@ResourceOAuth2RestTemplate template;@Overridepublic 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 {@ResourceOAuth2ClientContext context;@LoadBalanced   //和RestTemplate一样直接添加注解就行了@Beanpublic 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进行访问,这种模式是我们比较常见的模式。


https://www.fengoutiyan.com/post/15421.html

相关文章:

  • oauth20
  • 资源服务器
  • oauth协议
  • 腾讯云服务器
  • oa服务器地址和端口怎么查
  • 手机oa服务器地址和端口
  • oauth20协议
  • 购买云服务器
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機