UserDetailsService is required Algaworks Spring token

Estou seguindo um curso da algaworks e como o curso é um pouco antigo algumas coisas estão dando errado. Na criação do refresh token, quando tento fazer a requisição com o refresh token gerado a mensagem:

“error”: “server_error”,
“error_description”: “UserDetailsService is required.”

Segue meu código:

package com.example.algamoney.api.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@Configuration
@EnableWebSecurity
@EnableResourceServer
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
	
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
		auth
		.inMemoryAuthentication()
		.withUser("admin").password(encoder.encode("admin")).roles("ROLES");
		
	}
	
	public void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
		.antMatchers("/categoria/*").permitAll()
		.anyRequest().authenticated()
		.and()
		.httpBasic().and()
		.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
		.csrf().disable();
	}
	
	@Bean
	public AuthenticationManager authenticationManagerBean() throws Exception {
	    return super.authenticationManagerBean();
	}
	
}

package com.example.algamoney.api.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
	
	//CLASSE RESPONSAVEL POR GERAR O TOKEN
	
	@Autowired
	@Qualifier("authenticationManagerBean")
	AuthenticationManager authenticationManager;

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
		clients.inMemory() //EM MEMORIA NÃO É BANCO DE DADOS
			//withClient = CLIENT/APLICAÇÃO/SERVIÇO QUE VAI PEDIR TOKEN, NO CASO EXEMPLO SERIA UMA APLICAÇÃO ANGULAR. AS INFORMAÇÕES
			//TEM QUE SER AS MESMAS DO POSTMAN. NO POSTMAN SERÁ CONFIGURADO UM POST COM ESTA URL localhost:8080/oauth/token
			//AUTHORIZATION TYPE BASIC AUTH USERNAME angular PASSWORD linha debaixo secret. Será então gerado um token
			.withClient("angular") 
			.secret(encoder.encode("@ngul@r0")) //SENHA DO CLIENT
			.scopes("read", "write")
			//refresh_token é um granttype que implementa o refresg token, o refresh token vai renovar o token... ele expira e renova para dar segurança a aplicação.
			.authorizedGrantTypes("password", "refresh_token")
			//TEMPO DE DURAÇÃO DO TOKEN
			.accessTokenValiditySeconds(20)
			//esse tempo de duração de refresh token.. esta conta da 1 dia, então o usuario vai poder ficar 1 dia sem ter que logar novamente.
			//O refresh token vai gerar um novo access token que não precisa de login e senha, ou seja o usuario não vai precisar se logar de novo, ele vai gerar um novo access token
			// e isso dentro de cockies não sera possivel pegar via javascript
			.refreshTokenValiditySeconds(3600 * 24);
	}
	
//	@Override //ESTE MÉTODO FUNCIONA PARA VALIDAÇÃO DE TOKEN IN MEMORIA
//	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//		endpoints
//		.tokenStore(tokenStore())
//		.authenticationManager(authenticationManager);
//	}
	
	
	//ESTE MÉTODO PARA JWT verificar o token gerado no  https://jwt.io/
	@Override 
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints
		.tokenStore(tokenStore())
		//CONVERSOR DE TOKEN
		.accessTokenConverter(accessTokenConverter())
		.reuseRefreshTokens(false)
		.authenticationManager(authenticationManager);
	}
	
	@Bean //Tranformei em bean para quem precisar de um accesstoken pode usar
	public JwtAccessTokenConverter accessTokenConverter() {
		JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
		accessTokenConverter.setSigningKey("algaworks");
	return accessTokenConverter;
}

	@Bean
	public TokenStore tokenStore() {
		return new JwtTokenStore(accessTokenConverter());
	}
	
}

As imagens das chamadas no postman:

https://uploaddeimagens.com.br/imagens/g1B1zqY

https://uploaddeimagens.com.br/imagens/HpxpVow

Alguém poderia me ajudar?

Oi, conseguiu resolver ? estou neste mesmo problema, tem um curso mais atual para indicar ?

Cara desculpa a demora kkkk
consegui resolver criando a classe UserDetailsService.
Se você olhar no repositorio da algaworks vc consegue ver como criar… segue o numero do video que vc ta vendo e procura ele nos commits…
segue o link

1 curtida