• Spring Security OAuth2:资源服务器实现


    接着上一篇博客:https://www.cnblogs.com/wwjj4811/p/14504825.html

    概述

    资源服务器实际上就是对系统功能的增删改查,比如:商品管理、订单管理等资源,而在微服务架构中,而这每个资源实际上就是每一个微服务。当用户请求某个微服务资源时,首先通过认证服务器进行认证与授权,通过后再才可访问到对应资源。

    实现的功能:

    1. 要让他知道自己是资源服务器,系统知道这件事后,才会在前边加一个过滤器去验令牌(配置@EnableResourceServer 配置类)
    2. 要让他知道自己是什么资源服务器(配置资源服务器ID) ,配置去哪里验令牌,怎么验令牌,要带什么信息去验
    3. 进行资源的安全配置,让系统知道资源的每个访问权限是什么

    创建商品资源模块

    模块名:cloud-oauth2-resource-product

    依赖

    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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud-oauth2-parent</artifactId>
            <groupId>com.wj</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-oauth2-resource-product</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>com.wj</groupId>
                <artifactId>cloud-oauth2-base</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <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>
            <!-- 注册到 Eureka
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    创建启动类

    启动类com.wj.oauth2.ProductApplication

    @SpringBootApplication
    public class ProductApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProductApplication.class, args);
        }
    }
    

    创建访问资源

    com.wj.oauth2.web.controller.ProductController

    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
        @GetMapping("/list")
        @PreAuthorize("hasAuthority('product:list')")
        public R list() {
            List<String> list = new ArrayList<>();
            list.add("huawei");
            list.add("vivo");
            list.add("oppo");
            return R.ok(list);
        }
    }
    

    配置资源服务器

    创建com.wj.oauth2.resource.ResourceServerConfig类,继承ResourceServerConfigurerAdapter类

    @Configuration
    // 标识为资源服务器, 所有发往当前服务的请求,都会去请求头里找token,找不到或验证不通过不允许访问
    @EnableResourceServer
    //开启方法级别权限控制
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        //配置当前资源服务器的ID
        private static final String RESOURCE_ID = "product-server";
    
        /**当前资源服务器的一些配置, 如资源服务器ID **/
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            // 配置当前资源服务器的ID, 会在认证服务器验证(客户端表的resources配置了就可以访问这个服务)
            resources.resourceId(RESOURCE_ID)
                // 实现令牌服务, ResourceServerTokenServices实例
                .tokenServices(tokenService());
        }
    
        /**
         *  配置资源服务器如何验证token有效性
         *  1. DefaultTokenServices
         *     如果认证服务器和资源服务器同一服务时,则直接采用此默认服务验证即可
         *  2. RemoteTokenServices (当前采用这个)
         *     当认证服务器和资源服务器不是同一服务时, 要使用此服务去远程认证服务器验证
         * */
        @Bean
        public ResourceServerTokenServices tokenService() {
            // 资源服务器去远程认证服务器验证 token 是否有效
            RemoteTokenServices service = new RemoteTokenServices();
            // 请求认证服务器验证URL,注意:默认这个端点是拒绝访问的,要设置认证后可访问
            service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
            // 在认证服务器配置的客户端id
            service.setClientId("wj-pc");
            // 在认证服务器配置的客户端密码
            service.setClientSecret("wj-secret");
            return service;
        }
    }
    

    修改认证服务器的CustomUserDetailsService类:添加指定权限

    image-20210309134045866

    测试

    先用密码认证模式获取access_token

    image-20210309132229410

    然后请求http://localhost:8080/product/list,

    这里请求头需要加上Authorization,值是Bearer 加上空格再加上认证服务器获取到的access_token

    image-20210309132259594

    点击发送,我们就可以获取到指定资源了。

    控制令牌权限和授权规则

    1. 资源服务器通过ResourceServerConfigurerAdapter#configure(HttpSecurity http)指定授权规则。
    2. 禁用Session,因为是基于 token 认证,所以不需要 HttpSession 了指定资源的授权规则,与 SpringSecurity 中的指定方式一样
    3. 用#oauth2表达式控制令牌范围 scope,如果令牌的没有对应scope权限,则对应资源不允许访问

    ResourceServerConfig中重写父类方法:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
            //不创建session
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            //资源授权规则
            .authorizeRequests().antMatchers("/product/**").hasAuthority("product")
            //所有的请求对应访问的用户都要有all范围的权限
            .antMatchers("/**").access("#oauth2.hasScope('all')");
    }
    

    测试

    我们先将scope改掉

    image-20210309134541588

    image-20210309134555573

    再次访问,就会提示scope的错误

    image-20210309134612208

  • 相关阅读:
    JAVA基础知识|HTTP协议-两个特性
    JAVA基础知识|TCP/IP协议
    Spring Cloud|高可用的Eureka集群服务
    Hadoop环境搭建|第四篇:hive环境搭建
    C#中Func与Action的理解
    C# lambda表达式
    WPF ControlTemplate
    sublime text3插件安装及使用
    Dev Express之ImageComboBoxEdit,RepositoryItemImageComboBox使用方式
    SQL查询结果增加序列号
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14505081.html
Copyright © 2020-2023  润新知