Spring oauth:为什么资源服务器正在授权而不是授权服务器

时间:2017-11-23 21:29:17

标签: java spring spring-security oauth spring-security-oauth2

我在使用spring oauth框架时发现的是资源服务器向授权服务器发出check_token?token=T_O_K_E_N请求,授权服务器正在返回CheckTokenEndPoint映射,其中包含如下所示的权限。

{
    "exp": 1511471427,
    "user_name": "idvelu",
    "authorities": [
        "FUNCTION_GET_USERS",
        "FUNCTION_AUTHORITY_1",
        "FUNCTION_AUTHORITY_2",
        "FUNCTION_AUTHORITY_3",
        "FUNCTION_AUTHORITY_4",
        "FUNCTION_AUTHORITY_5",
        "FUNCTION_AUTHORITY_6",
        "FUNCTION_AUTHORITY_7",
    ],
    "client_id": "c1",
    "scope": [
        "read",
        "write"
    ]
}

使用oauth服务可视化,资源服务在两台不同的机器/ jvm中运行。

我认为现在资源服务器必须使用授权服务器的授权机构对ResourceServerConfiguration::configure(HttpSecurity)中配置的有效权限进行授权。

@Override
public void configure(HttpSecurity http) throws Exception {
 http.anonymous().disable().requestMatchers().antMatchers("/**").and().authorizeRequests()

        .antMatchers(HttpMethod.GET, "/myproject/users").hasAnyAuthority("FUNCTION_GET_USERS")
        .antMatchers(HttpMethod.POST, "/myproject/users").hasAnyAuthority("FUNCTION_POST_NEW_USER")
        .anyRequest().denyAll()
        .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}

在这种情况下,授权服务器可能会将所有数百个用户权限返回给资源服务器。相反,为什么授权服务器本身可以从资源服务器获取授权所需的少数权限作为查询参数
check_token?token=T_O_K_E_N&authorities=FUNCTION_GET_USERS,FUNCTION_AUTHORITY_2,..
,并通过DB对用户的功能进行验证?

最后我的问题是;我有不同的服务,如java,node.js,NGINX ......所有这些必须验证其对一个Spring授权服务器的身份验证和授权。由于上述问题,我的所有服务都必须实现授权(资源服务器)部分。意味着将用户的所有权限与API访问权限进行比较。
Java方面这种比较适用于spring资源服务器实现。但是所有其他非java(资源)服务都需要authorization / resourceServer实现。相反,如果我的spring授权服务器接受权限并验证,那么我的问题将作为单点授权/比较实现解决。我只需要将它作为check_token的一部分传递。

如何实现这个新的check_token端点以及接受权限?

1 个答案:

答案 0 :(得分:6)

授权服务器负责验证用户/客户端(取决于您使用的oauth类型)。完成后,会给出一个令牌。

当用户/客户端向资源服务器展示自己想要使用服务时,他们必须提供令牌。现在资源服务器有一个令牌,需要验证该令牌是否由授权服务器生成。有两种选择:

  1. 令牌本身不包含任何信息。资源服务器调用授权服务器并询问令牌是否有效。授权服务器将响应令牌有效并提供一些其他信息(用户/客户端,角色/范围等)。
  2. 令牌确实包含必要的信息(例如JWT tokes)。这使资源服务器能够在不联系授权服务器的情况下提取所需信息。在这种情况下,授权服务器已对令牌进行签名,资源服务器可以验证签名,以确保它是已颁发令牌的自动化服务器。
  3. 目前,您正在使用第一个方案。您编写的每个资源服务器都必须验证令牌并提取其他信息。验证的完成方式取决于授权服务器。

    2部分:

    我的问题不明确。我假设您使用OAuth2 authorization code方案与非JWT令牌?

    在这种情况下,您有一个仅负责身份验证的授权服务器,一个公开某些服务的资源服务器以及一个使用资源服务器的客户端。

    如果我没有误会,你有不同的资源服务器(api' s)?

    您没有共享授权服务器配置,但通常使用@EnableAuthorizationServer。这将创建一个端点/oauth/check_token。默认情况下,此端点不可行。你需要做这样的事情:

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception
    {
       oauthServer.checkTokenAccess("permitAll()"); // authenticated is better
    }
    

    您可以使用此端点验证令牌。

    所有这些都在oauth2 developer guide中进行了描述。

    3部分:

    在授权服务器上,您可以创建如下端点:

    @RequestMapping("/user")
    public Principal user(Principal principal) {
    
        if(principal instanceof OAuth2Authentication) {
            return (OAuth2Authentication) principal;
        } else {
            return principal;
        }
    }
    

    您可以根据需要进行修改。