问题
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 yourOAuth2RestTemplate
, 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