Authentication is required to obtain an access token (anonymous not allowed)

天涯浪子 提交于 2019-12-10 12:54:03

问题


I try to modify existing example - Tonr2 and Sparklr2. Also I viewed this tutorial based on Spring Boot Spring Boot OAuth2. I try to build application like in Tonr2 example but without first login (on tonr2). I just need one Authentication on Sparklr2 side. I do this:

@Bean
    public OAuth2ProtectedResourceDetails sparklr() {
        AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
        details.setId("sparklr/tonr");
        details.setClientId("tonr");
        details.setTokenName("oauth_token");
        details.setClientSecret("secret");
        details.setAccessTokenUri(accessTokenUri);
        details.setUserAuthorizationUri(userAuthorizationUri);
        details.setScope(Arrays.asList("openid"));
        details.setGrantType("client_credentials");
        details.setAuthenticationScheme(AuthenticationScheme.none);
        details.setClientAuthenticationScheme(AuthenticationScheme.none);
        return details;
    }

But I have Authentication is required to obtain an access token (anonymous not allowed) . I checked this question. Of course, my user is anonymous - I want to login on Sparklr2. Also, I tried different combinations of settings of this bean, but nothing good. How to fix it? How to make it work as I want?


回答1:


Almost two years late for the post.

The exception is thrown from AccessTokenProviderChain

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        if (auth instanceof AnonymousAuthenticationToken) {
            if (!resource.isClientOnly()) {
                throw new InsufficientAuthenticationException(
                    "Authentication is required to obtain an access token (anonymous not allowed)");
            }
        }

You either

  • Use ClientCredentialsResourceDetails in your OAuth2RestTemplate, or
  • Authenticate the user before using AuthorizationCodeResourceDetails to access external resources

In fact, in the tonr2 and sparklr2 example (I personally find the name very confusing), to access resources on sparklr2, a user has to first authenticate on tonr2. As seen in oauth2/tonr:

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("marissa").password("wombat").roles("USER").and().withUser("sam")
            .password("kangaroo").roles("USER");
}

If your user is anonymous, you might want to check for Single Sign On.

For whoever just want to quickly try out Oauth2 integration, add basic auth to your application:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .anyRequest().authenticated().and().httpBasic();
}

application.properties:

spring.security.user.password=password
spring.security.user.name=user

Don't forget to add spring-boot-starter-security to your project.

e.g. In gradle: compile 'org.springframework.boot:spring-boot-starter-security'

Or you can also disable AnonymousAuthenticationToken from creating by:

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



回答2:


Old post...

The exception indeed is thrown form AccessTokenProviderChain but it happens when spring security filters invoking if incorrect order. Make sure that your OpenIdAuthenticationFilter is invoking after OAuth2ClientContextFilter.



来源:https://stackoverflow.com/questions/38104983/authentication-is-required-to-obtain-an-access-token-anonymous-not-allowed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!