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

Kan*_*mar 3 java spring oauth spring-security spring-security-oauth2

我在使用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"
    ]
}
Run Code Online (Sandbox Code Playgroud)

只需使用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());
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,授权服务器可以将所有数百个用户权限返回给资源服务器.相反,为什么授权服务器本身不能
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端点以及接受权限?

Joh*_*anB 6

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

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

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

目前,您正在使用第一个方案.您编写的每个资源服务器都必须验证令牌并提取其他信息.验证的完成方式取决于授权服务器.

第2部分:

你的问题我不清楚.我假设您使用的authorization code是非JWT令牌的OAuth2 方案?

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

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

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

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

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

所有这些都在oauth2开发人员指南中描述.

第三部分:

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

@RequestMapping("/user")
public Principal user(Principal principal) {

    if(principal instanceof OAuth2Authentication) {
        return (OAuth2Authentication) principal;
    } else {
        return principal;
    }
}
Run Code Online (Sandbox Code Playgroud)

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