zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    使用 yo 命令行向导给 SAP UI5 应用添加一个新的视图
    SAP Fiori Elements 应用的 manifest.json 文件运行时如何被解析的
    SAP UI5 标准应用的多语言支持
    微软 Excel 365 里如何设置下拉菜单和自动高亮成指定颜色
    SAP Fiori Elements 应用里的 Title 显示的内容是从哪里来的
    本地开发好的 SAP Fiori Elements 应用,如何部署到 ABAP 服务器上?
    如何在 Cypress 测试代码中屏蔽(Suppress)来自应用代码报出的错误消息
    教你一招:让集群慢节点无处可藏
    应用架构步入“无服务器”时代 Serverless技术迎来新发展
    MySQL数据库事务隔离性的实现
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14505081.html
Copyright © 2011-2022 走看看