仅具有客户端凭据的Spring安全端点(基本)

Dan*_*nev 6 authentication spring spring-security spring-boot spring-security-oauth2

我有oauth2授权服务器和一个自定义端点(手动注销特定用户作为管理员)我希望这个端点使用其他客户端凭据(客户端ID和秘密作为基本编码头部值)进行保护,类似于/ oauth/check_token.

只能从具有特定范围的资源服务器调用此端点.

  1. 我需要检查客户端是否经过身份验证.
  2. 我希望能够在控制器的方法中添加@PreAuthorize("#oauth2.hasScope('TEST_SCOPE')").

我找不到任何文档或方法来使用Spring的机制进行客户端身份验证检查.

编辑1

我使用java配置而不是xml

Dan*_*nev 1

所以我最终得到了以下解决方案

认证管理器

public class ClientAuthenticationManager implements AuthenticationManager {

private ClientDetailsService clientDetailsService;
private PasswordEncoder passwordEncoder;

public HGClientAuthenticationManager(ClientDetailsService clientDetailsService, PasswordEncoder passwordEncoder) {
    Assert.notNull(clientDetailsService, "Given clientDetailsService must not be null!");
    Assert.notNull(passwordEncoder, "Given passwordEncoder must not be null!");
    this.clientDetailsService = clientDetailsService;
    this.passwordEncoder = passwordEncoder;
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    ClientDetails clientDetails = null;
    try {
        clientDetails = this.clientDetailsService.loadClientByClientId(authentication.getPrincipal().toString());
    } catch (ClientRegistrationException e) {
        throw new BadCredentialsException("Invalid client id or password");
    }
    if (!passwordEncoder.matches(authentication.getCredentials().toString(), clientDetails.getClientSecret())) {
        throw new BadCredentialsException("Invalid client id or password");
    }
    return new OAuth2Authentication(
            new OAuth2Request(null, clientDetails.getClientId(), clientDetails.getAuthorities(), true,
                    clientDetails.getScope(), clientDetails.getResourceIds(), null, null, null),
            null);
}
}
Run Code Online (Sandbox Code Playgroud)

过滤器声明

    private BasicAuthenticationFilter basicAuthenticationFilter() {
    ClientDetailsUserDetailsService clientDetailsUserDetailsService = new ClientDetailsUserDetailsService(
            this.clientDetailsService);
    clientDetailsUserDetailsService.setPasswordEncoder(this.passwordEncoder);
    return new BasicAuthenticationFilter(
            new ClientAuthenticationManager(this.clientDetailsService, this.passwordEncoder));
}
Run Code Online (Sandbox Code Playgroud)

过滤器注册

httpSecurity.addFilterBefore(this.basicAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
Run Code Online (Sandbox Code Playgroud)

警告!!!这将阻止任何其他类型的身份验证(oauth2 等)。 Basic接受身份验证,且适用于注册客户。