TokenEndpointAuthenticationFilter上的SecurityContextHolder.getContext()为null

kio*_*kar 5 java spring oauth-2.0 spring-boot spring-security-oauth2

我正在使用Spring BOOT + OAUTH2,并希望在成功登录后将用户对数据库注册表的访问权限保存起来...搜索解决方案我遇到了此类:https : //docs.spring.io/spring -security / oauth / apidocs / org / springframework / security / oauth2 / provider / endpoint / TokenEndpointAuthenticationFilter.html

所以我实现了这样的方法: CustomTokenEndpointAuthenticationFilter.java

public class CustomTokenEndpointAuthenticationFilter extends TokenEndpointAuthenticationFilter {

public CustomTokenEndpointAuthenticationFilter(AuthenticationManager authenticationManager, OAuth2RequestFactory oAuth2RequestFactory) {

    super(authenticationManager, oAuth2RequestFactory);
}

@Override
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException {

            /* on successful authentication do stuff here */

}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            /* before authentication check for condition if true then process to authenticate */
    if (!condition) {
        throw new AuthenticationServiceException("condition not satisfied");
    }
    super.doFilter(req, res, chain);
}
}
Run Code Online (Sandbox Code Playgroud)

还有我的AuthorizationServerConfiguration.java

@Configuration
@EnableAuthorizationServer

protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Inject
private DataSource dataSource;

@Inject
private JHipsterProperties jHipsterProperties;

@Bean
public TokenStore tokenStore() {
    return new JdbcTokenStore(dataSource);
}

/* create OAuth2RequestFactory instance */
private OAuth2RequestFactory oAuth2RequestFactory;

@Inject
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
    throws Exception {
    /* assign value in OAuth2RequestFactory instance */
    oAuth2RequestFactory = endpoints.getOAuth2RequestFactory();
    endpoints
        .tokenStore(tokenStore())
        .authenticationManager(authenticationManager);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    /* register TokenEndpointAuthenticationFilter with oauthServer */
    oauthServer
        .allowFormAuthenticationForClients()
        .addTokenEndpointAuthenticationFilter(new CustomTokenEndpointAuthenticationFilter(authenticationManager, oAuth2RequestFactory));

}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients
        .inMemory()
        .withClient(jHipsterProperties.getSecurity().getAuthentication().getOauth().getClientid())
        .scopes("read", "write")
        .authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
        .authorizedGrantTypes("password", "refresh_token", "authorization_code", "implicit")
        .secret(jHipsterProperties.getSecurity().getAuthentication().getOauth().getSecret())
        .accessTokenValiditySeconds(jHipsterProperties.getSecurity().getAuthentication().getOauth().getTokenValidityInSeconds());
}
}
Run Code Online (Sandbox Code Playgroud)

使用此设置,将调用此过滤器,但会发生异常:

“未找到客户端身份验证。请记住将过滤器放在TokenEndpointAuthenticationFilter的上游”

在对实现FilterTokenEndpointAuthenticationFilter类的进一步检查中,当SecurityContextHolder.getContext()。getAuthentication为null时,抛出此异常:

Authentication clientAuth = SecurityContextHolder.getContext().getAuthentication();
                if (clientAuth == null) {
                    throw new BadCredentialsException("No client authentication found. Remember to put a filter upstream of the TokenEndpointAuthenticationFilter.");
                }
Run Code Online (Sandbox Code Playgroud)

我搜索了许多站点,但是几乎不存在对此类实施的支持。提前致谢。