微服务认证系列二:SpringCloud OAuth2
微服务认证系列二:SpringCloud OAuth2
在微服务认证系列一:SpringCloud OAuth2中已经完成了对认证服务的搭建,接下来,将搭建资源服务,来通过认证服务来对资源服务进行认证
搭建资源服务器
-
创建项目:zhsl-cloud-oauth-client-9102
-
pom文件复制认证服务
-
Application.yml
server: port: 9101 spring: application: name: zhsl-cloud-oauth-client cloud: nacos: discovery: # 集群中各节点信息都配置在这里(域名-IP-绑定映射到各个实例的地址信息) server-addr: 127.0.0.1:8848
-
资源服务配置类
package com.example.zhslcloudoauthclient9102.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; 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; import org.springframework.security.oauth2.provider.token.RemoteTokenServices; /** * @Description: TODO * @Author: wanping * @Date: 6/20/22 **/ @Configuration @EnableResourceServer // 开启资源服务器功能 @EnableWebSecurity // 开启web访问安全 public class ResourceServerConfiger extends ResourceServerConfigurerAdapter { /** * 该方法用于定义资源服务器向远程认证服务器发起请求,进行token校验等事宜 * @param resources * @throws Exception */ @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { // super.configure(resources); // 设置当前资源服务的资源id resources.resourceId("autodeliver"); // 定义token服务对象(token校验就应该靠token服务对象) RemoteTokenServices remoteTokenServices = new RemoteTokenServices(); // 校验端点/接口设置 remoteTokenServices.setCheckTokenEndpointUrl("http://127.0.0.1:9100/oauth/check_token"); // 携带客户端id和客户端安全码 remoteTokenServices.setClientId("client_zhsl"); remoteTokenServices.setClientSecret("abcdef"); // 别忘了这一步 resources.tokenServices(remoteTokenServices); } /** * 场景:一个服务中可能有很多资源(API接口) * 某一些API接口,需要先认证,才能访问 * 某一些API接口,压根就不需要认证,本来就是对外开放的接口 * 我们就需要对不同特点的接口区分对待(在当前configure方法中完成),设置是否需要经过认证 * * @param http * @throws Exception */ @Override public void configure(HttpSecurity http) throws Exception { // super.configure(http); // 设置session的创建策略(根据需要创建即可) http.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .authorizeRequests() //autodeliver为前缀的请求需要认证 .antMatchers("/autodeliver/**") .authenticated() //demo为前缀的请求需要认证 .antMatchers("/demo/**") .authenticated() //其他请求不认证 .anyRequest().permitAll(); } }
测试
-
创建俩个controller:
-
需要权限的controller:DemoController
package com.example.zhslcloudoauthclient9102.controller; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Description: TODO * @Author: wanping * @Date: 6/20/22 **/ @RestController @RequestMapping("/demo") public class DemoController { @GetMapping("/test") public String findResumeOpenState() { Object details = SecurityContextHolder.getContext().getAuthentication().getDetails(); return "demo/test!"; } }
-
不需要权限访问的controller:Logincontroller
package com.example.zhslcloudoauthclient9102.controller; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Description: 权限放行方法 * @Author: wanping * @Date: 6/20/22 **/ @RestController @RequestMapping("/login") public class Logincontroller { @GetMapping("/test") public String findResumeOpenState() { return "login/test!"; } }
-
访问:http://127.0.0.1:9101/login/test 如下,可以访问
- 访问:http://127.0.0.1:9101/demo/test 如下,不能访问
-
-
将认证token携带进请求中,在访问
-
首先需要先更改认证服务中token的有效时间,之前的20秒太短了,不好测试,改为200秒
// 使用默认实现 DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setSupportRefreshToken(true); // 是否开启令牌刷新 defaultTokenServices.setTokenStore(tokenStore()); // 设置令牌有效时间(一般设置为2个小时) defaultTokenServices.setAccessTokenValiditySeconds(200); // access_token就是我们请求资源需要携带的令牌 // 设置刷新令牌的有效时间 defaultTokenServices.setRefreshTokenValiditySeconds(259200); // 3天 return defaultTokenServices;
-
接着。需要使用获取token方法重新获取一下令牌:http://127.0.0.1:9100/oauth/token?client_secret=abcdef&grant_type=password&username=admin&password=123456&client_id=client_zhsl
-
然后重新访问:http://127.0.0.1:9101/demo/test?access_token=2c2d79b4-0617-46c6-8c0e-d07cf469ea52
-
如上图,结论:已联通资源服务与认证服务的权限认证