我有以下代码,它可以完美地保护Amazon Alexa帐户链接 . 这是由一位现在离线的同事 Build 的(我正在拉夜班) .

@Configuration
@EnableWebSecurity

public class SkillRestConfiguration extends WebSecurityConfigurerAdapter {

    private static final String AMAZON_ALEXA_TOKEN_EXCHANGE_ROLE = "AMAZON-ALEXA-TOKEN-EXCHANGE";
    private static final String TOKEN_EXCHANGE_CLIENT_ID_KEY = "TOKEN_EXCHANGE_CLIENT_ID";
    private static final String TOKEN_EXCHANGE_CLIENT_SECRET_KEY = "TOKEN_EXCHANGE_CLIENT_SECRET";

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser(Environment.get(TOKEN_EXCHANGE_CLIENT_ID_KEY))
            .password(Environment.get(TOKEN_EXCHANGE_CLIENT_SECRET_KEY))
            .roles(AMAZON_ALEXA_TOKEN_EXCHANGE_ROLE);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();

        // Allow basic authentication from Amazon
        http.authorizeRequests()
            .antMatchers("/token").hasRole(AMAZON_ALEXA_TOKEN_EXCHANGE_ROLE)
            .and().httpBasic();
    }
}

但是,我想将其扩展为可用于Google帐户关联 . Google不发送基本身份验证标头,实际上它根本不发送授权标头,而是将client_id和client_secret作为POST数据传递 .

如何确保该部分在/ token endpoints 中也“经过身份验证”?例如支持这两种身份验证方法?如果我在/ token上获得POST请求,其中client_id和client_secret匹配预定义的环境变量,则可以通过基本身份验证或POST数据来允许 .

这就像添加以下代码一样简单吗?

http.antMatchers("/token")
    .formLogin()
    .permitAll()
    .usernameParameter("client_id")
    .passwordParameter("client_secret");

如果是这样,我应该在'http.authorizeRequests()'调用之后或之前放置它吗?

edit: 通过做一些额外的研究,我认为我需要创建自己的过滤器和身份验证提供程序 . 过滤器将从请求中提取用户名和密码,如果我理解正确,则在securitycontext上设置它 . 只有在没有基本身份验证标头且POST包含正确值的情况下才应执行此操作 . 我想我可以使用以下代码完成此操作,方法是将UsernamePasswordAuthenticationToken扩展为ClientIdAndSecretAuthenticationToken .

@Override
public boolean supports(Class<?> authentication) {
    return (ClientIdAndSecretAuthenticationToken.class.isAssignableFrom(authentication));
}

http.antMatchers("/token")
    .addFilterBefore(clientIdAndSecretAuthenticationFilter, ClientIdAndSecretAuthenticationFilter.class)
    .authenticationProvider(clientIdAndSecretAuthenticationProvider)

我在这里温暖吗?