天天看点

权限认证(五):OAuth2资源服务器

  • ​重点​

认证服务器和资源服务器是服务端,可以看成是微信;
第三方客户端则是客户端,可以看成第三方的网站
用户在认证服务器认证成功后,再去资源服务器获取用户的相关资源

资源服务器是提供给第三方客户端使用的
如果没有第三方客户端,所有子模块都是自己内部的子系统,则使用单点登录即可      
  • 新建一个demo06,在demo05的基础上开发,确保能够跑通
  • 由于使用jdbc管理第三方应用,所以查看数据库
  • 权限认证(五):OAuth2资源服务器
  • 任意使用一种模式获取token
  • 权限认证(五):OAuth2资源服务器
  • 检查该令牌是否有效,查看拥有的权限
  • 权限认证(五):OAuth2资源服务器
  • 测试通过
  • ​资源服务器的使用​

  • 新建子模块resource
  • 编写pom.xml
<dependencies>
        <dependency>
            <artifactId>base</artifactId>
            <groupId>com.ychen.oauth2</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--spring mvc相关的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Security、OAuth2 和JWT等 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <!-- springboot 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--热部署 ctrl+f9-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>      
  • 编写启动类
@SpringBootApplication
public class ProductResourceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductResourceApplication.class, args);
    }
}      
  • 编写控制层接口,模拟一些资源
@RestController
@RequestMapping("/product")
public class ProductController {
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('product')")
    public MengxueguResult list() {
        List<String> list = new ArrayList<>();
        list.add("眼镜");
        list.add("格子衬衣");
        list.add("双肩包");
        return MengxueguResult.ok(list);
    }
}      
  • 拓展
@PreAuthorize("hasAuthority('product')")
# 表示在令牌有效的前提下,还要拥有product权限才能访问该资源,即如下检查令牌时查看是否拥有权限      
权限认证(五):OAuth2资源服务器
  • 编写配置类
@Configuration
@EnableResourceServer // 标识为资源服务器,请求服务中的资源,就要带着token过来,找不到token或token是无效访问不了资源
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级别权限控制
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    public static final String RESOURCE_ID = "product-server";
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // 当前资源服务器的资源id,认证服务会认证客户端有没有访问这个资源id的权限,有则可以访问当前服务
        resources.resourceId(RESOURCE_ID)
                .tokenServices(tokenService())
        ;
    }
    public ResourceServerTokenServices tokenService(){
        // 远程认证服务器进行校验 token 是否有效
        RemoteTokenServices service = new RemoteTokenServices();
        // 请求认证服务器校验的地址,默认情况 这个地址在认证服务器它是拒绝访问,要设置为认证通过可访问
        service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
        service.setClientId("mengxuegu-pc");
        service.setClientSecret("mengxuegu-secret");
        return service;
    }

}      
  • 拓展
RESOURCE_ID = "product-server"
# 表示在认证服务器中认证成功后,配置了可以访问的资源,由于认证服务器中配置的是product-server,所以为了测试这个资源服务器先配置为product-server
# 检查令牌时,可查看该token可访问的资源id      
权限认证(五):OAuth2资源服务器
  • 启动认证服务器模块和资源服务器模块进行测试
  • 浏览器访问如下,获取授权码
http://localhost:8090/auth/oauth/authorize?client_id=mengxuegu-pc&response_type=code      
  • 输入用户名和密码,并同意授权,之后得到一个授权码
  • 权限认证(五):OAuth2资源服务器
    权限认证(五):OAuth2资源服务器
  • 通过授权码模式得到一个token
  • 权限认证(五):OAuth2资源服务器
  • 检查令牌是否有效,有效则可以查看拥有的权限
  • 权限认证(五):OAuth2资源服务器
  • 拿到令牌去资源服务器获取资源,测试通过
  • 权限认证(五):OAuth2资源服务器
  • ​资源服务器的权限配置​

# 当用户在认证服务器中使用授权码模式,获取授权码的时候,会指定第三方的客户端可以访问服务端的哪些资源
# 而资源服务器的权限配置,则是用于限制服务端的不同资源需要不同的权限

# 第1层权限:RESOURCE_ID = "product-server";表示访问当前资源服务器需要的权限
# 第2层权限:scope=all,表示访问该资源服务器中的某些资源所需的权限
# 第3层权限:.antMatchers("/product/*").hasAuthority("product");表示具体某个接口所需的权限      
  • 代码实现
# ResourceServerConfig配置类下添加如下
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                // SpringSecurity不会使用也不会创建HttpSession实例
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeRequests()
                // 授权规则配置,表示拥有product权限的token才能访问/product/*路径下的接口
                .antMatchers("/product/*").hasAuthority("product")
                // 所有请求,都需要有all范围(scope)
                .antMatchers("/**").access("#oauth2.hasScope('all')")
                // 等价于上面
//                .anyRequest().access("#oauth2.hasScope('all')")
            ;
    }      
  • 拓展
.antMatchers("/product/*").hasAuthority("product")
# 表示拥有product权限的令牌才能访问/product/*路径下的资源,可在检查令牌时查看拥有的权限

.antMatchers("/**").access("#oauth2.hasScope('all')")
# 表示拥有all授权标识的令牌才能访问/**路径下的资源,可在检查令牌时查看拥有的授权标识      

继续阅读