401 не авторизован при использовании токена для запроса предоставленной пользовательской информации на сервере Spring oauth2 - PullRequest
0 голосов
/ 03 мая 2020

При следующей конфигурации я могу получить токен. Но при использовании токена для запроса информации о пользователе на этом сервере ответ 401 не авторизован. Что еще более странно, информация о пользователе может быть возвращена, используя имя пользователя / пароль, вместо использования какого-либо токена. Я также попробовал это с авторизацией почтальона oauth2, какой бы токен я ни поставил, если cook ie верен, информация о пользователе будет возвращена. Я сравнил код со многими учебниками и не смог найти проблему. настроить сервер oauth2:

@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("customizedClientDetailsService")
    ClientDetailsService clientDetailsService;

    AuthenticationManager authenticationManager;

    public AuthorizationServerConfig(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        this.authenticationManager = authenticationConfiguration.getAuthenticationManager();
    }

    /**
     * Exposes 2 endpoints for checking tokens. By default, they are denyAll(). To allow get token (using code) through
     * /oauth/token, tokenKeyAccess should be permitAll().
     *
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .authenticationManager(this.authenticationManager)
                .accessTokenConverter(accessTokenConverter())
                .tokenStore(tokenStore());
    }

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

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        // converter.setKeyPair(this.keyPair); // Using RSA private key to encrypt.
        converter.setSigningKey("myscretekey");
        return converter;
    }

настроить пользователя:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * Using in memory user for demo. In practice, it is loaded from redis or db table.
     * @return
     */
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withDefaultPasswordEncoder()
                        .username("enduser")
                        .password("password")
                        .roles("USER")
                        .build());
    }

настроить клиента:

@Component("customizedClientDetailsService")
public class CustomizedClientDetailsService implements ClientDetailsService {

    /**
     * Local initialized clientDetails for demo.
     * @param clientId
     * @return
     * @throws ClientRegistrationException
     */
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        BaseClientDetails details = new BaseClientDetails();
        details.setClientId("first-client");
        details.setClientSecret("{noop}noonewilleverguess");
        // could be one or many of "authorization_code", "password", "client_credentials", "implicit", "refresh_token"
        details.setAuthorizedGrantTypes(Arrays.asList("authorization_code", "refresh_token"));
        details.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
        details.setScope(Arrays.asList("read", "write")); // Without a given scope, Spring security kept asking for grant.
        details.setRefreshTokenValiditySeconds(1800);
        details.setAccessTokenValiditySeconds(1800);
        Set<String> set = new HashSet<>();
        set.add("http://localhost:8080/oauth/login/client-app");
        details.setRegisteredRedirectUri(set);
        return details;
    }
}

информация о пользователе:

@RestController
public class UserInfoController {

    @GetMapping("user/info")
    public Object getUserInfo() {
        Authentication a = SecurityContextHolder.getContext().getAuthentication();
        return  a.getPrincipal();
    }
}

получить токен:

curl -X POST \
  'http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=first-client&client_secret=noonewilleverguess&code=b19dqe'

получить информацию о пользователе:

curl -X GET \
  http://localhost:8080/user/info \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODg1MTE2NjgsInVzZXJfbmFtZSI6ImVuZHVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiZmViZDgzMTMtMjllMS00M2M4LWEzNGUtMTU5OWM0NmYyNTE4IiwiY2xpZW50X2lkIjoiZmlyc3QtY2xpZW50Iiwic2NvcGUiOlsicmVhZCJdfQ.0rq-tFnA9amh7LT-3wyCN1GK9ZpF1ry9rsN-kXT4Xec'
...