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

是否可以在spring Security中使用refresh令牌请求acces令牌oauth2?没有基本的身份验证?

胥诚
2023-03-14

我想知道在spring中oauth2是否可以使用另一个刷新令牌获得一对新的令牌(访问令牌和刷新令牌),而不需要基本的身份验证(没有clientId和clientSecret,有没有办法?

例如:

具有基本身份验证

curl-u clientid:clientsecret-x POST'http://myapplication.oauth2/accounts/oauth/token?grant_type=refresh_token&client_id= &refresh_token='-v

没有基本身份验证

curl-u-x POST'http://myapplication.oauth2/accounts/oauth/token?grant_type=refresh_token&client_id= &refresh_token='-v

我注意到spring中的sprint BasicAuthenticationFilter使用了validation bellow,可能会重写这个过滤器并使身份验证仅使用refresh令牌。

String header = request.getHeader("Authorization");

if (header == null || !header.toLowerCase().startsWith("basic ")) {
  chain.doFilter(request, response);
  return;
}

共有1个答案

贺福
2023-03-14

简短的回答是否定的。用于管理Spring OAuth2endpoint的类如下所示:

@FrameworkEndpoint
public class TokenEndpoint extends AbstractEndpoint

我的意思是,getAccess TokenRefresh两个请求都使用具有不同参数的相同endpoint。管理这些问题的方法是:

@RequestMapping(
  value = {"/oauth/token"},
  method = {RequestMethod.POST}
)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
  if (!(principal instanceof Authentication)) {
    throw new InsufficientAuthenticationException("There is no client authentication. Try adding an appropriate authentication filter.");
  } else {
    String clientId = this.getClientId(principal);
    ... 

如您所见,需要principal对象(在本例中由基本身份验证提供)。

甚至,如果您将项目的安全性配置为允许该url,而不检查身份验证,您将在上述方法中实现“Enter”,但您将收到InsulficentAuthenticationException,因为没有提供authentication实例。

1.创建自定义AuthenticationProvider将不起作用,因为前面调用了PostAccessToken方法。因此您将收到InsulficentAuthenticationException

2.创建OncePerRequestFilter并将其配置为在处理当前请求之前执行:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http...
        .anyRequest().authenticated()
        .and()
        .addFilterBefore(myCustomFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
      web.ignoring()
            .antMatchers(POST, "/accounts/oauth/**");
    }

代码“类似于”:

@Component
public class CustomAuthenticationFilter extends OncePerRequestFilter {

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                FilterChain filterChain) throws ServletException, IOException {
    ...
    SecurityContextHolder.getContext().setAuthentication(
            new UsernamePasswordAuthenticationToken("existingUser",
                    "passwordOfExistingUser",
                    Collections.emptyList()));
    ...
    filterChain.doFilter(request, response);
}

这种方法的问题是TokenEndpoint中的主体来自HttpServletRequest而不是来自Spring上下文,您可以看到正在调试BasicAuthenticationFilter类。

在自定义筛选器中,您可以尝试使用反射在userprincipal属性中设置一个值,但是,正如您所验证的,request有几个“内部request属性”,这可能是一个“太棘手的选项”。

总之,Oauth标准需要用户/通行证来访问资源,如果您想要在几乎所有提供的endpoint中解决问题,可能该项目不是您要寻找的。

我不建议这样做,但如果您仍然希望继续使用这种方法,那么可以在TokenEndpoint类接收的Principal参数中包含您自己的值。

重要的是要考虑basicauthorizationfilter仍然会被执行,但是您可以用自己的一个对象覆盖Spring主体对象。

为此,我们可以重用以前的customauthenticationfilter,但现在您必须包含您需要的过滤器,我的意思是,允许的URL、参数等,您要“打开大门”,所以要小心您允许的和不允许的。

这种情况下的不同之处在于,不是在扩展WebSecurityConfigurerAdapter的类中添加配置,而是在:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

  @Autowired
  private CustomAuthenticationFilter customAuthenticationFilter;
  ...

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) {
    security.checkTokenAccess("isAuthenticated()");
    security.addTokenEndpointAuthenticationFilter(customAuthenticationFilter);
  }
  ...
 类似资料:
  • 我正在构建一个基于令牌的身份验证(Node.js使用带有angular客户端的passport/JWT)。 用户输入凭证后,他将获得一个访问令牌,并在头中的每个请求中发送该令牌(头:bearer token)。 我不想每次他的访问令牌过期时都提示登录请求(我猜大约每天),我听说过刷新令牌。刷新令牌永不过期(或很少过期),并且能够无限期续订令牌。当访问令牌即将过期时,客户端可以通过发送刷新令牌来发送

  • 有没有办法对/oauth/tokenendpoint禁用HTTP基本身份验证?我希望在JSON主体或请求头中发送client_id和client_secret。 我想工作的卷曲例子: 或

  • 我在身份验证中使用基于令牌的方法,但在许多博客中,我读到他们将令牌存储在数据库中。 我们需要将令牌存储在DB中的基于令牌的身份验证中吗? https://scotch.io/tutorials/the-ins-and-outs-of-token-based-authentication 在这个博客中,提到我们正在签署令牌而不是存储在数据库中,我认为这应该是实现真正无状态的方法。

  • 我试图使用Spring cloud Oauth2实现Oauth-2.0-Cookbook一书中的示例。 我设法实现了他的功能,但不幸的是,我面临一个问题:为了进行成功的调用,我必须提供基本的身份验证凭据(): Github源 我喜欢在POST请求撤销令牌时进行某种身份验证的想法,但我不认为Angular SPA应用程序应该始终保留用户名和密码,以便成功调用。 一般情况下,Google上的解决方案只

  • 我正在尝试向正在运行的本地服务器发出GET请求。我无法返回正确的数据,我看到“未经授权”的响应。如果字符串“token”是正确的,那么任何人都能发现任何明显的问题吗。 }* 我能够从命令行获得一个curl请求:

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