spring-attic / spring-security-oauth

Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.
http://github.com/spring-projects/spring-security-oauth
Apache License 2.0
4.69k stars 4.05k forks source link

Handling error: UnsupportedGrantTypeException, Unsupported grant type: password #1328

Open NABEEL-AHMED-JAMIL opened 6 years ago

NABEEL-AHMED-JAMIL commented 6 years ago

Hello, I'm new on Spring-Security-oauth-2 if face this error grant_typepassword error

and my code below as

@Component
public class AccountAuthenticatoinProvider extends AbstractUserDetailsAuthenticationProvider {

    private final Logger log = LoggerFactory.getLogger(AccountAuthenticatoinProvider.class);

    @Autowired
    private UserDetailsService userDetailsService;
    /**
     * A PasswordEncoder instance to hash clear test password values.
     */
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails,
             UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {

        if(usernamePasswordAuthenticationToken.getCredentials() == null || userDetails.getPassword() == null) {
            throw new BadCredentialsException("Credentials mya not be null.");
        } else if(!passwordEncoder.matches((String) usernamePasswordAuthenticationToken.getCredentials(), userDetails.getPassword())) {
            throw new BadCredentialsException("Invalid Credentials");
        }
    }

    @Override
    protected UserDetails retrieveUser(String s, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
            throws AuthenticationException {

        UserDetails userDetails = userDetailsService.loadUserByUsername(s);

        return userDetails;
    }
}

@Configuration
public class AdditionalWebConfig {
    /**
     * Allowing all origins, headers and methods here is only intended to keep this example simple.
     * This is not a default recommended configuration. Make adjustments as
     * necessary to your use case.
     *
     */
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private final Logger log = LoggerFactory.getLogger(AuthorizationServerConfiguration.class);

    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private AuthorityRepository authorityRepository;
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;
    @Autowired
    private DeviceUtil deviceUtil;
    @Autowired
    private BuiltInUtil builtInUtil;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // @formatter:off
        clients.jdbc(dataSource).
                withClient("barco").
//                resourceIds("ballistic").
                scopes(builtInUtil.getPrivilegs()).
                authorities(builtInUtil.getAuthoritys())
                .authorizedGrantTypes(getAllGrantType()).
                secret("ballistic").
                accessTokenValiditySeconds(deviceUtil.getToken()).
                refreshTokenValiditySeconds(deviceUtil.getRefreshToken());
        // @formatter:on
    }

    private String[] getAllGrantType() {
        return new String[] {"password","refresh_token","client_credentials","authorization_code"};
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // @formatter:off
        final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(new CustomTokenEnhancer()));
        endpoints.
                authenticationManager(authenticationManager).
                tokenStore(tokenStore).
                tokenEnhancer(tokenEnhancerChain);
        // @formatter:on
    }

}

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private final Logger log = LoggerFactory.getLogger(CustomAuthenticationEntryPoint.class);

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
           AuthenticationException e) throws IOException, ServletException {

        log.info("Pre-authenticated entry point called. Rejection access");
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
    }
}

@Component
public class CustomLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
        implements LogoutSuccessHandler {

    private final Logger log = LoggerFactory.getLogger(CustomLogoutSuccessHandler.class);

    private static final String BEARER_AUTHENTICATION = "Bearer ";
    private static final String REFRESH_TOKEN = "refresh_token";
    private static final String HEADER_AUTHORIZATION = "authorization";

    @Autowired
    private TokenStore tokenStore;

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                Authentication authentication) throws IOException, ServletException {
        // fetch token's from the http-rtbrequest
        String token = httpServletRequest.getHeader(HEADER_AUTHORIZATION);
        String refreshToken = httpServletRequest.getHeader(REFRESH_TOKEN);
        // check if not null and start with 'Bearer' and not null refreshToken
        if((token != null && token.startsWith(BEARER_AUTHENTICATION)) && (refreshToken != null)) {

            // Condition true and spilt to access the token and remove from the token-store
            OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token.split(" ")[1]);
            OAuth2RefreshToken oAuth2RefreshToken = tokenStore.readRefreshToken(refreshToken);

            if((oAuth2AccessToken != null) && (oAuth2RefreshToken != null)) {
                // remove process after getting the token
                tokenStore.removeAccessToken(oAuth2AccessToken);
                tokenStore.removeRefreshToken(oAuth2RefreshToken);
            }
        }
        // return the 'Response with 'Ok response''
        httpServletResponse.setStatus(HttpServletResponse.SC_OK, "{success:You are logout}");
    }
}
public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {

        try {

            ((DefaultOAuth2AccessToken) oAuth2AccessToken).
                    setAdditionalInformation(getAdditionalInfo(oAuth2Authentication));
            return oAuth2AccessToken;

        }catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private Map<String, Object> getAdditionalInfo(OAuth2Authentication oAuth2Authentication) {

        UserDetailsUtil loginUser = (UserDetailsUtil) oAuth2Authentication.getPrincipal();

        final Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("authorities", loginUser.getAuthorities());
        additionalInfo.put("username", loginUser.getUsername());
        additionalInfo.put("isEnabled",  loginUser.isEnabled());
        additionalInfo.put("account_Expired", loginUser.isAccountNonExpired());
        additionalInfo.put("account_locked", loginUser.isAccountNonLocked());
        additionalInfo.put("credentials_expired", loginUser.isCredentialsNonExpired());
        additionalInfo.put("device", loginUser.getDevice());

        return additionalInfo;
    }
}
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new OAuth2MethodSecurityExpressionHandler();
    }

}

/**
 * Created by Nabeel on 1/11/2018.
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    private final Logger log = LoggerFactory.getLogger(ResourceServerConfiguration.class);

    @Value("${server.contextPath}")
    private String api;

    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // @formatter:off
        resources.resourceId("ballistic").tokenStore(tokenStore);
        // @formatter:on
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.sessionManagement().
                sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.httpBasic().
                realmName("Spring Boot JWT Example Realm").
                and().
                exceptionHandling().
                authenticationEntryPoint(customAuthenticationEntryPoint).
                and().
                logout().
                logoutUrl(LOGOUT).
                logoutSuccessHandler(customLogoutSuccessHandler);
        http.csrf().
                requireCsrfProtectionMatcher(new AntPathRequestMatcher(AUTHORIZE)).
                disable().
                headers().
                frameOptions().
                disable().
                and().
                authorizeRequests().
                antMatchers(api+AUTH+REGISTER, api+AUTH+ACTIVATED, api+AUTH+RESETPASSWORD,api+AUTH+LOSTPASSWORD).
                permitAll().
                antMatchers(QR_SECURE, SPRITE).authenticated();
        // @formatter:on
    }

    @Bean
    public BuiltInUtil builtInUtill() { return new BuiltInUtil(); }

}
/**
 * Created by Nabeel on 1/11/2018.
 */
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;

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

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}
@Component
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {

    private final Logger log = LoggerFactory.getLogger(UserDetailsService.class);

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {

//        log.info("login {}", login);
        String lowercaseLogin = login.toLowerCase();
        User userFromDatabase;
        if(lowercaseLogin.contains("@")) {
//            log.info("email--- {}", login);
            userFromDatabase = userRepository.findByEmail(lowercaseLogin);
        } else {
//            log.info("username--- {}", login);
            userFromDatabase = userRepository.findByUsernameCaseInsensitive(lowercaseLogin);
        }

        return authProcess(userFromDatabase, lowercaseLogin);
    }

    private UserDetailsUtil authProcess(User userFromDatabase, String lowercaseLogin) {

        // we can put this into single condition but log error creation problem will you face
        if ( userFromDatabase == null) {
//            log.error("Exception--- {}", "User name Not found");
            throw new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database");
        } else if (userFromDatabase.getAuthoritys() == null || userFromDatabase.getAuthoritys().isEmpty()) {
//            log.error("Exception--- {}", "User name Not found");
            throw new UsernameNotFoundException("User " + lowercaseLogin + " is not possible due to the authority NULL");
        } else if (getPrivileges(userFromDatabase.getAuthoritys()) == null) {
//            log.error("Exception--- {}", "User name Not found");
            throw new UsernameNotFoundException("User " + lowercaseLogin + " is not possible due to the privilege NULL");
        } else if (!userFromDatabase.isActivated()) {
//            log.error("Exception--- {}", "User Not Activate Account found");
            throw new UserNotActivatedException("User " + lowercaseLogin + " is not activated yet");
        } else {
//            log.info("getting role--- {}", userFromDatabase.getAuthoritys().toString());
            return new UserDetailsUtil(userFromDatabase, getAuthorities(userFromDatabase.getAuthoritys()), getPrivileges(userFromDatabase.getAuthoritys()));
        }
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Collection<Authority> authorities) {

        return getGrantedAuthorities(getPrivileges(authorities));
    }

    private List<String> getPrivileges(Collection<Authority> authorities) {

        List<String> privileges = new ArrayList<>();
        List<Privilege> collection = new ArrayList<>();
        for (Authority authority : authorities) {
            collection.addAll(authority.getPrivileges());
        }
        for (Privilege item : collection) {
            privileges.add(item.getPrivilege());
        }
        return privileges;
    }

    private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }

}
JohnNiang commented 6 years ago

https://docs.spring.io/spring-security-oauth2-boot/docs/current-SNAPSHOT/reference/htmlsingle/

danscheibe commented 6 years ago

Same here. GrantType Password is not working with the latest version.

mmatsumoto1973 commented 6 years ago

It also occurs in 2.3.0.RELEASE.

Insomnium commented 6 years ago

I'm not convinced, but it seems that Spring Security team expressed some thoughts on this topic. They recommend not to use password grant type, if I'm not mistaken. Anyway, I've looked through some code and found something interesting in AuthorizationServerEndpointsConfigurer.getDefaultTokenGranters:

private List<TokenGranter> getDefaultTokenGranters() {
        ClientDetailsService clientDetails = clientDetailsService();
        AuthorizationServerTokenServices tokenServices = tokenServices();
        AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
        OAuth2RequestFactory requestFactory = requestFactory();

        List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();
        tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails,
                requestFactory));
        tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
        ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
        tokenGranters.add(implicit);
        tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
        if (authenticationManager != null) {
            tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                    clientDetails, requestFactory));
        }
        return tokenGranters;
    }

So, if you expose AuthenticationManager as a bean in context like this:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    // ...
}

password grant type begin working

P.S.: I'm using 2.3.3.RELEASE version

rickywu commented 5 years ago

The same problem with oauth2-2.0.14

I use the same Jenkins docker image build project, but it throws exception if compile on CentOS 7.5 and works well if compile on Ubuntu 16.04

CentOS 7.5:

Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-25T03:49:05+08:00) Maven home: /usr/share/apache-maven-3.5.3 Java version: 1.8.0_171, vendor: Oracle Corporation Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre Default locale: en, platform encoding: UTF-8 OS name: "linux", version: "4.4.0-134-generic", arch: "amd64", family: "unix"

Ubuntu 16.04

Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-25T03:49:05+08:00) Maven home: /usr/share/maven/apache-maven-3.5.3 Java version: 1.8.0_171, vendor: Oracle Corporation Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre Default locale: en, platform encoding: UTF-8 OS name: "linux", version: "3.10.0-862.6.3.el7.x86_64", arch: "amd64", family: "unix"

Only the kernel version is different.

And still not work if upgrade oauth2-2.3.3

amimob9 commented 5 years ago

I am also facing the same issue, password grant not supported

dengjfeng commented 5 years ago

I catched the issue on Windows10. { "error": "unsupported_grant_type", "error_description": "Unsupported grant type: password" } But I have set the "password" grant_type to the table oauth_client_details. But it works well on CentOS 7.4.1708

IcebergXTY commented 5 years ago

I'm not convinced, but it seems that Spring Security team expressed some thoughts on this topic. They recommend not to use password grant type, if I'm not mistaken. Anyway, I've looked through some code and found something interesting in AuthorizationServerEndpointsConfigurer.getDefaultTokenGranters:

private List<TokenGranter> getDefaultTokenGranters() {
      ClientDetailsService clientDetails = clientDetailsService();
      AuthorizationServerTokenServices tokenServices = tokenServices();
      AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
      OAuth2RequestFactory requestFactory = requestFactory();

      List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();
      tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails,
              requestFactory));
      tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
      ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
      tokenGranters.add(implicit);
      tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
      if (authenticationManager != null) {
          tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                  clientDetails, requestFactory));
      }
      return tokenGranters;
  }

So, if you expose AuthenticationManager as a bean in context like this:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    // ...
}

password grant type begin working

P.S.: I'm using 2.3.3.RELEASE version

Thanks a lot, It works!

rickywu commented 5 years ago

@Insomnium There is an override-ed method in author's example and mine, but still got this exception.

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
jorisschellekens commented 5 years ago

Same problem. Can the spring security team please look into this?

nrheckman commented 5 years ago

I too had this issue, and it was not entirely resolved by exposing an authenticationManagerBean.

I was able to get things working though by setting the exposed bean on the AuthorizationServerEndpointsConfigurer.

  @Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    // ...
    private AuthenticationManager authenticationManagerBean;
    @Autowired
    public void setAuthenticationManagerBean(AuthenticationManager authenticationManagerBean) {
        this.authenticationManagerBean = authenticationManagerBean;
    }
    // ...
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenStore(tokenStore())
                .authenticationManager(authenticationManagerBean)
                .tokenServices(tokenServices())
                .userApprovalHandler(userApprovalHandler())
                .authorizationCodeServices(authorizationCodeServices());
    }
    // ...
  }
jgrandja commented 5 years ago

@jorisschellekens Have you tried both suggestions as per this comment and this one?

If neither of these work for you, please provide a minimal sample that reproduces the issue and I can take a look at it.

bitamin-on-git commented 5 years ago
  @Autowired
  public void setAuthenticationManagerBean(AuthenticationManager authenticationManagerBean) {
      this.authenticationManagerBean = authenticationManagerBean;
  }

These lines in my AuthorizationServerConfigurerAdapter extension give me the expected result. Thanks @nrheckman.

an0nh4x0r commented 5 years ago

I too had this issue, and it was not entirely resolved by exposing an authenticationManagerBean.

I was able to get things working though by setting the exposed bean on the AuthorizationServerEndpointsConfigurer.

  @Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
      // ...
      private AuthenticationManager authenticationManagerBean;
      @Autowired
      public void setAuthenticationManagerBean(AuthenticationManager authenticationManagerBean) {
          this.authenticationManagerBean = authenticationManagerBean;
      }
      // ...
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
          endpoints.tokenStore(tokenStore())
                  .authenticationManager(authenticationManagerBean)
                  .tokenServices(tokenServices())
                  .userApprovalHandler(userApprovalHandler())
                  .authorizationCodeServices(authorizationCodeServices());
      }
      // ...
  }

Thanks a lot. Finally now I can go home.

gudpick commented 4 years ago

Please do find the code below. This works perfectly fine for me.

@Configuration
@EnableAuthorizationServer
public class AuthServer extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManagerBean;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .authenticationManager(authenticationManagerBean);
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().
                withClient("client").
                secret(passwordEncoder.encode("secret")).
                authorizedGrantTypes("password").
                scopes("webclient","mobileclient");
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password(passwordEncoder.encode("user") ).roles("USER");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
its-me-praveen commented 4 years ago

Please do find the code below. This works perfectly fine for me.

@Configuration
@EnableAuthorizationServer
public class AuthServer extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManagerBean;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .authenticationManager(authenticationManagerBean);
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().
                withClient("client").
                secret(passwordEncoder.encode("secret")).
                authorizedGrantTypes("password").
                scopes("webclient","mobileclient");
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password(passwordEncoder.encode("user") ).roles("USER");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

Not working for 2.2.7.RELEASE

mavortius commented 3 years ago

I'm not convinced, but it seems that Spring Security team expressed some thoughts on this topic. They recommend not to use password grant type, if I'm not mistaken. Anyway, I've looked through some code and found something interesting in AuthorizationServerEndpointsConfigurer.getDefaultTokenGranters:

private List<TokenGranter> getDefaultTokenGranters() {
      ClientDetailsService clientDetails = clientDetailsService();
      AuthorizationServerTokenServices tokenServices = tokenServices();
      AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
      OAuth2RequestFactory requestFactory = requestFactory();

      List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();
      tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails,
              requestFactory));
      tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
      ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
      tokenGranters.add(implicit);
      tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
      if (authenticationManager != null) {
          tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                  clientDetails, requestFactory));
      }
      return tokenGranters;
  }

So, if you expose AuthenticationManager as a bean in context like this:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    // ...
}

password grant type begin working

P.S.: I'm using 2.3.3.RELEASE version

Yes, you're right! Thank!

(PS.: using SB version: 2.4.0)