简体   繁体   English

如何在线创建和验证onedrive或sharepoint的webhook?

[英]How can I create and validate webhooks for onedrive or sharepoint online?

I want a subscription to my OneDrive folder. 我想订阅我的OneDrive文件夹。 After a successful authorization and receiving the access token for my OneDrive, I can work with all of my folders and files in OneDrive. 成功授权并收到OneDrive的访问令牌后,我可以使用OneDrive中的所有文件夹和文件。 But I fail to create a subscription. 但是我没有创建订阅。

I am implementing a Java Spring Boot Application which is already deployed to Azure and is available by eg https://{tenant}.westeurope.cloudapp.azure.com/api 我正在实现一个已经部署到Azure的Java Spring Boot应用程序,例如https:// {tenant} .westeurope.cloudapp.azure.com / api

When I try to create a subscription, I receive a response code: 400 with the message: "Validation request failed. Must respond with 200 OK to this request." 当我尝试创建订阅时,收到响应代码:400,并显示消息:“验证请求失败。必须以200 OK响应此请求。”

After reading all of the wonderful documentation , I could not find a solution for my problem. 阅读完所有精彩的文档后 ,我无法找到解决问题的方法。 Maybe I misunderstood some general setup things. 也许我误解了一些常规设置。

These are my endpoint's: 这些是我的终点:

@RestController
@CrossOrigin
public class OneDriveSubscriptionsController {

    @Autowired
    private SubscriptionService subscriptionService;

    // Should be used to create a subscription
    @RequestMapping(method=RequestMethod.GET, value="/create")
    public ResponseEntity<?> create() {

        OneDriveSubscriptionVO subscription = new OneDriveSubscriptionVO();
        oneDriveSubscriptionService.createSubscription(subscription);
        return new ResponseEntity<String>("", HttpStatus.OK);
    }

    // Should be used to validate a subscription
    @RequestMapping(method=RequestMethod.POST, value="/create")
    public ResponseEntity<?> validation(@RequestParam String validationtoken) {

        ResponseEntity<String> response = new ResponseEntity<String>(validationtoken, HttpStatus.OK);
        return response;
    }

    // Should be used to receive notification's.
    @RequestMapping(method=RequestMethod.POST, value="/notification" consumes=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> subscriptionUpdate(@RequestBody OneDriveSubscriptionVO subscription) {
        // working with received notifications.
    }
}

My service class: 我的服务类:

@Service
public class SubscriptionService {

    public synchronized String create(OneDriveSubscriptionVO subscription) {
        String url = "https://graph.microsoft.com/v1.0/subscriptions";
        String authorization = "Bearer "+AccessInformation.getAccess_token();
        HttpClient httpclient = HttpClients.createDefault();
        String ret = null;

            try {
                URIBuilder builder = new URIBuilder(url);
                URI uri = builder.build();

                String serialisedJsonString = Util.serializeJson(subscription); 
                StringEntity entity = new StringEntity(serialisedJsonString);

                HttpPost request = new HttpPost(uri);
                request.setEntity(entity);
                request.setHeader("Authorization", authorization);
                request.setHeader("Content-Type", "application/json");

                HttpResponse response = httpclient.execute(request);
                HttpEntity responseEntity = response.getEntity();

                ret = EntityUtils.toString(responseEntity);

        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        return ret;
    }
}

My helper class: 我的助手班:

public class Util {
    private <T>String serializeJson(T obj) {
        Gson gson;
        GsonBuilder builder = new GsonBuilder(); 
        builder.setPrettyPrinting(); 
        gson = builder.create(); 
        return gson.toJson(obj);
    }
}

My OneDriveSubscriptionVO class (simplified): 我的OneDriveSubscriptionVO类(简化):

@JsonIgnoreProperties(ignoreUnknown = true)
public class OneDriveSubscriptionVO {

    private String id;
    private String clientState;
    private String expirationDateTime;
    private String notificationUrl;
    private String resource;
    private String changeType;

    public OneDriveSubscriptionVO() {
        this.clientState = "random string";
        this.expirationDateTime = "2019-05-15T11:23:00.000Z";
        this.notificationUrl= "https://{tenant}.westeurope.cloudapp.azure.com/api/notification";
        this.resource = "/me/drive/root";
        this.changeType = "updated";
    }

So far as i know, I have to create a subscription with the data from my OneDriveSubscriptionVO Constructor. 据我所知,我必须使用OneDriveSubscriptionVO构造函数中的数据创建订阅。 Within 5 seconds I have to response with the received validationtoken. 在5秒钟内,我必须回复收到的validationtoken。

After sending the creation data i receive the error "Validation request failed. Must respond with 200 OK to this request." 发送创建数据后,我收到错误“验证请求失败。必须以200 OK响应此请求”。 and no validationtoken to enable the subscription. 并且没有validationtoken来启用订阅。

This is the json which I want to use to create the subschription: 这是我想用来创建子类的json:

{
  "clientState": "random string",
  "expirationDateTime": "2019-05-15T11:23:00.000Z",
  "notificationUrl": "https://{tenant}.cloudapp.azure.com/onedrive/api/notification",
  "resource": "/me/drive/root",
  "changeType": "updated"
}

This is what I receive: 这是我收到的:

{
  "error": {
    "code": "InvalidRequest",
    "message": "Subscription validation request failed. Must respond with 200 OK to this request.",
    "innerError": {
      "request-id": "5bf8a5e2-efd4-4863-bdc3-1fb7c89afa83",
      "date": "2019-04-16T11:43:58"
    }
  }
}

I think something is generally wrong, because no endpoint are triggered after my "create subscription POST Request". 我认为通常是错误的,因为在我的“创建订阅POST请求”之后没有触发端点。

The validation request is sent to the same endpoint as the notifications. 验证请求将发送到与通知相同的端点。 It looks like you're expecting the validation to be done against /create while the endpoint you specify for the notifications is /notification . 看起来您期望在为通知指定的端点是/notification/create进行验证。 You'll want to merge implementation of POST-to-/create with POST-to-/notification. 您将要将POST-to- / create的实现与POST-to- / notification合并。 Here's a sample Azure Function that will give you an idea what this looks like: 这是一个示例Azure函数,可以让您了解它的外观:

#r "Newtonsoft.Json"
 
using System;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;
 
public static async Task<object> Run(HttpRequestMessage request, TraceWriter log)
{
    var content = await request.Content.ReadAsStringAsync();

    var query = request.RequestUri.Query
        .TrimStart('?')
        .Split('&')
        .Where(x => !String.IsNullOrEmpty(x))
        .Select(x => x.Split('='))
        .ToDictionary(x => x[0], x => Uri.UnescapeDataString(x[1]).Replace("+", " "), StringComparer.OrdinalIgnoreCase)
        ?? new Dictionary<string,string>();

    string token;

    if (query.TryGetValue("validationToken", out token))
    {
        var response = request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(token)));
        return response;
    }
 
    return request.CreateResponse(HttpStatusCode.OK, "Done!");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM