首页 > 解决方案 > 具有 OAuth2 身份验证的独立 SpringBoot 应用程序

问题描述

我正在使用 springboot 创建一个应用程序,该应用程序将使用具有 OAuth2 身份验证的 API。成功获取承载代码后,我将调用另一个 API,该 API 实际上会为我提供进一步处理的数据。我有自定义 OAuth url、授权码、用户名、密码、密钥、api 密钥。当我在互联网上搜索时,没有一个示例使用所有这些[仅使用了密钥、授权码和 api 密钥。]。我还需要使用用户名和密码吗?

我尝试了下面的代码[和其他一些东西]。但无法通过这个。

    <code>
        import java.util.ArrayList;
        import java.util.Arrays;
        import java.util.List;
        import javax.xml.bind.DatatypeConverter;
        import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.client.support.BasicAuthorizationInterceptor;
    import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
    import org.springframework.security.oauth2.client.OAuth2RestOperations;
    import org.springframework.security.oauth2.client.OAuth2RestTemplate;
    import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
    import org.springframework.security.oauth2.client.token.AccessTokenRequest;
    import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
    import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.extern.slf4j.Slf4j;
    @Slf4j
    @Component
    public class ApiConsumer {
        @Autowired
        private RestTemplate template;
        @Value("${oauth.api}")
        String url;
        @Value("${oauth.oAuth.url}")
        String oAuthUrl;
        @Value("${oauth.user}")
        String username;
        @Value("${oauth.password}")
        String password;
        @Value("${oauth.apikey}")
        String apiKey;
        @Value("${oauth.secretkey}")
        String apiSecret;
        public String postData() {
            log.info("Call API");
            try {
                String response = consumeApi();
                if (response.equals("200")) {
                    log.info("posting data to another api");
                    // CALL another  API HERE for actual data with bearer code
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
        private String consumeApi() throws Exception {
            String authorizationHeader = "Basic "
                    + DatatypeConverter.printBase64Binary((apiKey + ":" + apiSecret).getBytes());
                    // setting up the HTTP Basic Authentication header value
            HttpHeaders requestHeaders = new HttpHeaders();
            // set up HTTP Basic Authentication Header
            requestHeaders.add("Authorization", authorizationHeader);
            requestHeaders.add("Accept", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
            requestHeaders.add("response_type", "code");
            // request entity is created with request headers
            HttpEntity<String> request = new HttpEntity<String>(requestHeaders);
            template.getInterceptors().add(new BasicAuthorizationInterceptor(username, password));
            ResponseEntity<String> result = null;
            try {
                result = template.exchange(oAuthUrl, HttpMethod.POST, request, String.class);
                log.info( result.getBody());
                if (result.getStatusCode() == HttpStatus.OK) {

                    transformData(result.getBody());
                }
                if (result.getStatusCode() != HttpStatus.REQUEST_TIMEOUT) {
                    throw new Exception("Api taking too long to respond! ");
                }
            }
            catch (Exception e) {
                log.error("Api taking too long to respond!");
            }
            return "";
        }
        private void transformData(String body) throws JsonMappingException, JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            List<HeapEntity> heapEntityList = Arrays.asList(mapper.readValue(body, HeapEntity[].class));
            if (heapEntityList != null && heapEntityList.size() > 0) {
                heapEntityList.forEach(i -> i.getPhoneNumber().replaceAll("-", ""));
            }
            log.debug("Size of list is :: " + heapEntityList.size());
            heapEntityList.add(null);

        }

    }
    </code>

标签: spring-bootoauth-2.0spring-security-oauth2

解决方案


不幸的是,我无法直接回答您的问题,因为您无法从中明确您尝试使用哪种授权类型,这将决定您是否需要使用用户名和密码的问题的答案。

我建议您熟悉RFC 6749 的第 4 节,您将在其中找到有关该标准支持的所有授权类型以及它们所需的请求参数的信息。

密码授权类型的示例:

如果您需要使用RestTemplate,您可以执行以下操作:

HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/x-www-form-urlencoded");
headers.set("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()));

String body = String.format("grant_type=password&username=%s&password=%s", username, password);

String json = restTemplate.postForObject(tokenUrl, new HttpEntity<>(body, headers), String.class);

请注意,响应是一个包含令牌的 json 对象,而不是令牌本身。

或者您可以简单地使用更适合您的目的OAuth2RestTemplate

@Bean
public OAuth2RestTemplate oAuth2RestTemplate() {
    ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
    resource.setClientAuthenticationScheme(AuthenticationScheme.form);
    resource.setAccessTokenUri("tokenUrl");
    resource.setClientId("clientId");
    resource.setClientSecret("clientSecret");
    resource.setUsername("username");
    resource.setPassword("password");
    return new OAuth2RestTemplate(resource);
}

不要忘记添加@EnableOAuth2Client到您的配置类之一。


推荐阅读