代码之家  ›  专栏  ›  技术社区  ›  Daniel Donev

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

  •  6
  • Daniel Donev  · 技术社区  · 6 年前

    我有oauth2授权服务器和一个自定义端点(以管理员身份手动注销特定用户) 我希望使用rest客户机凭据(客户机id和secret作为基本编码头值)保护此端点,类似于/oauth/check\u令牌。

    只能从具有特定作用域的资源服务器调用此终结点。

    1. 我希望能够在控制器的方法中添加@PreAuthorize(“#oauth2.hasScope('TEST\u SCOPE')”)。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Donev    6 年前

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

    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);
    }
    }
    

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

    过滤器注册

    httpSecurity.addFilterBefore(this.basicAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
    

    这将阻止任何其他类型的身份验证(oauth2等)。 仅限 Basic 仅限 对于注册客户。

        2
  •  0
  •   JohanB    6 年前

    @PreAuthorize("#oauth2.hasScope('TEST_SCOPE')") 关于控制器的方法应该足够了。如果客户端未通过身份验证,则没有可用的作用域,并且作用域检查将失败。

    @PreAuthorize("isAuthenticated()") 要检查客户端是否经过身份验证,请执行以下操作: https://docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/reference/htmlsingle/#el-common-built-in

    HttpSecurity 而不是和 @PreAuthorize