[译]在 Spring 中实现 OAuth2:使用范围(第 2 部分)

我们在上一篇文章中了解了基本的 OAuth2 概念以及如何在 Spring 中实现和执行不同的授权。在这篇文章中,我们将介绍 OAuth2 的另一个重要概念:范围。

OAuth 范围

保护对应用程序的访问通常分两个步骤进行:身份验证和授权。要理解这两个概念,假设您在绝密政府大楼工作。在开始之前,你会得到一张卡片,可以让你进入建筑物。 OAuth 令牌可以看作是允许您访问的卡片。

一旦你进去,你决定去三楼见你的一位同事,在尝试使用你的卡打开三楼的门后,你听到一声嘟嘟声,告诉你你没有被授权。在 OAuth 中,范围是一种定义令牌可以访问哪些资源以及不能访问哪些资源的方法。范围允许访问控制,并且可以被视为相当于传统身份验证中的用户角色。

实现

为了演示范围,我们将使用第 1 部分中的示例

资源服务器的控制器中,我们有以下端点:

typescript 复制代码
@RestController("/")
public class ResourceController {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @GetMapping("/foo")
    public String foo(){
        return "foo";
    }

    @PostMapping("/bar")
    public String bar(){
        return "bar";
    }

    @DeleteMapping("/test")
    public String test(){
        return "test";
    }
}

第一步是使用所需的范围配置授权服务器

arduino 复制代码
 clients.inMemory().withClient("my-trusted-client")
                .authorizedGrantTypes("password",
                        "refresh_token", "implicit", "client_credentials", "authorization_code")
                .authorities("CLIENT")
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(60)
                .redirectUris("http://localhost:8081/test.html")
                .resourceIds("resource")
                .secret("mysecret");

要在资源服务器中启用范围检查,我们有两个选项:使用安全配置或使用方法安全性。

  • 使用安全配置:
scss 复制代码
	@Override
	public void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
			 .antMatchers(HttpMethod.GET,"/hello").access("#oauth2.hasScope('read')")
			 .antMatchers(HttpMethod.GET,"/foo").access("#oauth2.hasScope('read')")
			 .antMatchers(HttpMethod.POST,"/bar").access("#oauth2.hasScope('write')")
			 .antMatchers(HttpMethod.DELETE,"/test").access("#oauth2.hasScope('trust')")
			.anyRequest().authenticated().
			 and().csrf().disable();
	}
  • 使用方法安全性:
kotlin 复制代码
    @PreAuthorize("#oauth2.hasScope('read')")
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @PreAuthorize("#oauth2.hasScope('read')")
    @GetMapping("/foo")
    public String foo(){
        return "foo";
    }

    @PreAuthorize("#oauth2.hasScope('write')")
    @PostMapping("/bar")
    public String bar(){
        return "bar";
    }

    @PreAuthorize("#oauth2.hasScope('trust')")
    @DeleteMapping("/test")
    public String test(){
        return "test";
    }

另外,我们需要将 @EnableGlobalMethodSecurity(prePostEnabled = true) 添加到 Spring 可以获取的任何类( @Configuration@Service 等)。在我们的示例中,我们已将其添加到 ResourceSecurityConfiguration 类中。 prePostEnabled = true 告诉 Spring 启用前注解和后注解,例如 @PreAuthorize@PostFilter 等......

对于那些想了解 #oauth2.hasScope('trust') 这样的表达式的人来说,它们是使用 Spring 表达式语言(SpEL)构建的。

行动范围

默认情况下,如果令牌请求中不存在范围,Spring 会假定令牌具有所有配置的范围。让我们首先请求一个具有 read 范围的令牌:

bash 复制代码
curl -X POST --user my-trusted-client:mysecret localhost:8081/oauth/token -d 'grant_type=client_credentials&client_id=my-trusted-client&scope=read' -H "Accept: application/json"

回复:

json 复制代码
{
  "access_token": "acadbb31-f126-411d-ae5b-6a278cee2ed6",
  "token_type": "bearer",
  "expires_in": 60,
  "scope": "read"
}

现在,我们可以使用令牌来访问具有 read 范围访问权限的端点:

bash 复制代码
 curl -XGET localhost:8989/hello -H "Authorization: Bearer acadbb31-f126-411d-ae5b-6a278cee2ed6"

 hello

curl -XGET localhost:8989/foo -H "Authorization: Bearer acadbb31-f126-411d-ae5b-6a278cee2ed6"

 foo

现在,让我们尝试在仅接受 write 范围的端点上使用此令牌:

bash 复制代码
curl -XPOST localhost:8989/bar -H "Authorization: Bearer acadbb31-f126-411d-ae5b-6a278cee2ed6"

回复:

json 复制代码
{
  "error": "access_denied",
  "error_description": "Access is denied"
}

由于令牌不具有所需的范围,因此访问被拒绝。让我们尝试获取一个具有 write 范围的新令牌,然后重试:

bash 复制代码
curl -X POST --user my-trusted-client:mysecret localhost:8081/oauth/token -d 'grant_type=client_credentials&client_id=my-trusted-client&scope=write' -H "Accept: application/json"

回复:

json 复制代码
{
  "access_token": "bf0fa83a-23bd-4633-ac6c-a06f40d53e5f",
  "token_type": "bearer",
  "expires_in": 3599,
  "scope": "write"
}
bash 复制代码
curl -XPOST localhost:8989/bar -H "Authorization: Bearer bf0fa83a-23bd-4633-ac6c-a06f40d53e5f"

bar

总结

范围是 OAuth 的一个重要方面,因为令牌不携带有关其用户或请求者的信息。范围允许限制对资源的访问,以实现更好的访问控制和安全性。在下一篇文章中,我们将了解如何将 Google 和 Facebook 等外部 OAuth 提供商集成到流程中。

原文链接:www.zakariaamine.com/2018-03-01/...

相关推荐
qq_441996056 分钟前
Mybatis官方生成器使用示例
java·mybatis
巨大八爪鱼12 分钟前
XP系统下用mod_jk 1.2.40整合apache2.2.16和tomcat 6.0.29,让apache可以同时访问php和jsp页面
java·tomcat·apache·mod_jk
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田2 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
魔道不误砍柴功4 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
枫叶_v4 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
wclass-zhengge4 小时前
SpringCloud篇(配置中心 - Nacos)
java·spring·spring cloud
路在脚下@4 小时前
Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点和适用场景
java·spring boot·servlet
黑马师兄4 小时前
SpringBoot
java·spring