当前位置: 首页 > 知识库问答 >
问题:

Spring Security OAUTH2-InfallyentAuthenticationException:需要身份验证才能获得访问令牌(不允许匿名)

鲜于宏义
2023-03-14

我试图理解为什么客户端中的匿名用户不能获得访问令牌。

我在Spring博客上找到了这篇关于这个主题的帖子,Dave Syer对此做出了回答:

请记住,这是一个与客户端应用程序有关的问题,而不是auth服务器,所以请尝试从cllient的角度来看它。在步骤1。有一个用户试图访问受保护的资源。如果您不能对该用户进行身份认证,那么您的所有用户最终都将获得相同的访问令牌(第一个用户使用他在auth服务器上的凭据获得的访问令牌)。这绝对是个坏主意。

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    if (auth instanceof AnonymousAuthenticationToken) {
        if (!resource.isClientOnly()) {
            throw new InsufficientAuthenticationException(
                    "Authentication is required to obtain an access token (anonymous not allowed)");
        }
    }

共有1个答案

楚俊逸
2023-03-14

我相信这不是真的与会议有关。Dave的意思可能是在spring上下文中只能有一个匿名用户。对我来说,匿名用户这个术语为什么会存在一直是个谜,但它的故事不同。

查看JDBCClientTokenServices类中GetAccessStoken方法的代码

public OAuth2AccessToken getAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {

    OAuth2AccessToken accessToken = null;

    try {
        accessToken = jdbcTemplate.queryForObject(selectAccessTokenSql, new RowMapper<OAuth2AccessToken>() {
            public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
                return SerializationUtils.deserialize(rs.getBytes(2));
            }
        }, keyGenerator.extractKey(resource, authentication));
    }
    catch (EmptyResultDataAccessException e) {
        if (LOG.isInfoEnabled()) {
            LOG.debug("Failed to find access token for authentication " + authentication);
        }
    }

    return accessToken;
}

它在数据库中使用序列化身份验证。因此,即使在不同的会话中,它也将使用相同的匿名用户来加载令牌,有效地加载了完全相同的令牌。

authorization_codeoauth2流中,您需要code来获取令牌(因此,第一步是请求代码,只有在授权用户之后才会给出代码-在此步骤中,用户可能会被重定向到比如说facebook)。第二步是通过给出代码来获取标记。code在db中具有有限授权,因此spring知道谁是新令牌的所有者:

\d+ oauth_code;
                                                     Table "mydb.oauth_code"
     Column     |          Type          |                        Modifiers                        | Storage  | Stats target | Description
----------------+------------------------+---------------------------------    ------------------------+----------+--------------+-------------
 id             | integer                | not null default     nextval('oauth_code_id_seq'::regclass) | plain    |              |
 authentication | bytea                  |                                                         | extended |              |
 code           | character varying(255) |                                                         | extended |              |

因此,总而言之,如果您要用相同的令牌填充OAuth2ClientContext,那么将SessionRequest带范围的OAuth2ClientContext将没有帮助。

 类似资料:
  • 让我们举一个例子,其中SPA使用OIDC隐式流访问API。 由于OAuth作用域是粗粒度的,因此通常需要在资源服务器上执行额外的授权。例如,当通过endpoint访问动态资源(例如文件系统)时,可能会出现这种情况——在endpoint中,访问受到与用户ID相关的权限的限制,但仅使用OAuth作用域是不实际的,因为资源具有动态性。 在这些情况下,endpoint本身可以受到OAuth范围的保护,而对

  • } 要获取令牌,我执行以下步骤: > 使用浏览器转到:http://localhost:9000/oauth/authorize?response_type=code&client_id=test&redirect_uri=http%3a%2f%2flocalhost%3a8080%2f&scope=write 首先,它将我重定向到一个登录表单,在那里我输入用户名和密码:admin abc 请帮我

  • 在我的Jitsi Meet Prodody配置文件中:~/。jitsi meet cfg/prosody/config/conf.d 我有以下配置: 有了它,我可以通过令牌进行身份验证。 但是,如果我不指定任何令牌,例如: https://jitsi.mydummyserver.com/test 然后我得到以下提示询问用户和密码: 有没有办法只允许令牌身份验证并完全摆脱那个提示? 谢谢

  • 我有一个LaravelAPI(实际上是LumenAPI)服务于VueJS前端。Vue应用程序允许用户登录到谷歌。然后将Google令牌发送回Lumen API,后者使用Google验证令牌,然后验证电子邮件地址是否为有效用户。然后它生成一个令牌,与用户一起存储在数据库中,并返回用户对象。 我没有使用Passport或jwt auth之类的东西。那么现在,我如何使用默认的Auth中间件来验证(现在已

  • 我试图弄清楚我应该如何坚持身份验证。 假设用户使用电子邮件和密码成功进行身份验证。然后服务器生成并返回两个令牌: accesstoken(jwt过期15分钟)将存储在浏览器存储中 refreshtoken(jwt过期7天)作为安全cookie 当将访问令牌存储在本地存储(或会话存储)中时,React 应用程序将简单地检查它是否存在于存储中并继续渲染私有路由。因此,这意味着如果用户有一个无效/被盗的

  • 我在springboot 1.5.6.RELEASE中使用oauth2,在oauth2中使用jdbc认证。 我添加了属性: 1-授权服务器配置适配器: 2资源服务器配置 3-安全配置 我正在尝试使用postman生成一个令牌,并向url<code>发送post请求http://localhost:8082/dawam2/oauth/token?grant_type=password我使用基本身份验