由于缺少CSRF'保留状态',Spring-Oauth2访问令牌请求永远不会成功

 幸福抉择2502901973 发布于 2022-12-04 01:44

在过去的几天里,我一直在使用spring-security-oauth2来实现spring boot/spring security /和java配置.我已经设法解决了大部分困难,但我对现在出了什么问题感到难过.

我正在成功完成以下步骤:

将用户发送给提供商以授权应用程序代表他们行事

系统会提示用户按安全性登录提供程序

用户授权应用程序,重定向URL将它们发送回原始URL的客户端应用程序以及?code=asdfa&state=asdfasf查询字符串

此时,我相信无论使用什么,都AuthorizationCodeResourceDetails应该为访问令牌交换授权代码和客户端应用凭证.这是进程因以下堆栈跟踪而失败的地方.

 Caused by: org.springframework.security.oauth2.common.exceptions.InvalidRequestException: Possible CSRF detected - state parameter was present but no state could be found
    at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getParametersForTokenRequest(AuthorizationCodeAccessTokenProvider.java:246)
    at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:198)
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:142)
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:564)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:529)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:261)
    at com.pvr.apps.admin.user.UserServiceImpl.getAllUsers(UserServiceImpl.java:51)
    at com.pvr.apps.admin.web.IndexController.serveUserList(IndexController.java:35)

客户端上的东西看起来像(我@EnableOAuth2Client在主配置上也有一个注释).

@Component
public class UserServiceImpl implements UserService {

    @Resource
    @Qualifier("accessTokenRequest")
    private AccessTokenRequest accessTokenRequest;

    public OAuth2ProtectedResourceDetails createResource() {
        AuthorizationCodeResourceDetails resourceDetails = new AuthorizationCodeResourceDetails();
        resourceDetails.setScope(Lists.newArrayList("read", "write"));
        resourceDetails.setClientId("admin");
        resourceDetails.setClientSecret("password");
        resourceDetails.setAuthenticationScheme(AuthenticationScheme.query);
        resourceDetails.setAccessTokenUri("http://provider.com:8080/oauth/token");
        resourceDetails.setUserAuthorizationUri("http://provider.com:8080/oauth/authorize");
        return resourceDetails;
    }

    @Override
    public List getAllUsers() {

        RestTemplate template = new OAuth2RestTemplate(createResource(), new DefaultOAuth2ClientContext(accessTokenRequest));

        ResponseEntity responseEntity = template.getForEntity("http://provider.com:8080/users/", User[].class);
        return Lists.newArrayList(responseEntity.getBody());
    }
}

在提供商方面:

授权服务器配置:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{

    @Autowired
    private LoginUrlAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private AuthenticationManager authenticationManager;


    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
                .authenticationEntryPoint(authenticationEntryPoint)
                .tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
                .checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();

        endpoints
                .authenticationManager(authenticationManager)
                .accessTokenConverter(converter)
                .tokenStore(new JwtTokenStore(converter));
    }


    // TODO: this should read from a db
    public void configure(ClientDetailsServiceConfigurer clientConfigurer) throws Exception {
        clientConfigurer.inMemory()
                .withClient("admin").secret("password")
                .authorizedGrantTypes(
                        GrantType.PASSWORD.type,
                        GrantType.AUTHORIZATION_CODE.type,
                        GrantType.IMPLICIT.type,
                        GrantType.REFRESH_TOKEN.type
                )
                .authorities("ROLE_TRUSTED_CLIENT")
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(60);
    }
}

和资源服务器配置:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailService;

    @Autowired
    AuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
            .and()
                .formLogin()
                    .loginProcessingUrl("/login.do")
                    .usernameParameter("uid")
                    .passwordParameter("pwd")
                    .loginPage("/login")
                    .failureUrl("/login?error=true")
            .and()
                .userDetailsService(userDetailService);
    }

}

Dave Syer.. 5

它正在寻找的状态将在,OAuth2ClientContext但由于你刚刚创建了一个新的,它在需要时超出了范围.如果你注入一个来自@EnableOAuth2Client它的那个,@Scope("session")那么它将会在那里,它将能够为你解决状态.GitHub中的所有样本都以这种方式工作.或者你可以自己管理持久性,我想.

1 个回答
  • 它正在寻找的状态将在,OAuth2ClientContext但由于你刚刚创建了一个新的,它在需要时超出了范围.如果你注入一个来自@EnableOAuth2Client它的那个,@Scope("session")那么它将会在那里,它将能够为你解决状态.GitHub中的所有样本都以这种方式工作.或者你可以自己管理持久性,我想.

    2022-12-11 02:11 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有