如何使用技巧为虚拟助手Bot实施OAuth提示身份验证

时间:2019-08-12 18:13:12

标签: c# azure oauth-2.0 azure-active-directory botframework

我跟随step-by-step docs将身份验证添加到sample skill,作为通过Virtual Assistant Template创建的虚拟助手程序的一部分。

我已经为该技能创建了一个Azure Active Directory V2应用程序注册,并在Azure门户的技能机器人中添加了一个链接到该应用程序的OAuth连接。我还在该技能的appsettings.json中更新了OAuthConnections。

appsettings.json

  "oauthConnections": [
    {
      "name": "calendarconnection",
      "provider": "Azure Active Directory v2"
    }
    . . .

但是我仍然停留在如何实现OAuth提示流程以使用户从虚拟助手登录到技能方面的知识,因为虚拟助手模板是以特定方式构建的,即MainDialog继承自RouterDialog。

public class MainDialog : RouterDialog
{
    public MainDialog(
            BotSettings settings,
            BotServices services,
            OnboardingDialog onboardingDialog,
            EscalateDialog escalateDialog,
            CancelDialog cancelDialog,
            List<SkillDialog> skillDialogs,
            IBotTelemetryClient telemetryClient,
            UserState userState)
            : base(nameof(MainDialog), telemetryClient)
    {
        . . .
    }

    . . .

    protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
    {
        . . .
    }
    . . .
    protected override async Task<InterruptionAction> OnInterruptDialogAsync(DialogContext dc, CancellationToken cancellationToken)
    {
        . . .
    }
    . . .

在这种情况下,与分步文档中显示的代码有什么不同?

更新: 我添加了一个新对话框LoginDialog,并从OnStartAsync

启动了它

MainDialog.cs

        public MainDialog(
            BotSettings settings,
            BotServices services,
            ResponseManager responseManager,
            ConversationState conversationState,
            UserState userState,
            ProactiveState proactiveState,
            CreateEventDialog createEventDialog,
            ChangeEventStatusDialog changeEventStatusDialog,
            TimeRemainingDialog timeRemainingDialog,
            SummaryDialog summaryDialog,
            UpdateEventDialog updateEventDialog,
            ConnectToMeetingDialog connectToMeetingDialog,
            UpcomingEventDialog upcomingEventDialog,
            LoginDialog loginDialog,               // added
            OAuthPrompt oAuthPrompt,               // added
            ConfirmPrompt confirmPrompt,           // added
            IBotTelemetryClient telemetryClient)
            : base(nameof(MainDialog), telemetryClient)
        {
            _settings = settings;
            _services = services;
            . . .

            AddDialog(loginDialog);
            AddDialog(oAuthPrompt);
            AddDialog(confirmPrompt);

        }
        . . .
        protected override async Task OnStartAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
        {
            await dc.BeginDialogAsync(nameof(LoginDialog));
            // send a greeting if we're in local mode
            await dc.Context.SendActivityAsync(_responseManager.GetResponse(CalendarMainResponses.CalendarWelcomeMessage));
        }
        . . .

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
 . . .
     services.AddTransient<LoginDialog>();
     services.AddTransient<OAuthPrompt>();
     services.AddScoped<ConfirmPrompt>(_ => new ConfirmPrompt(nameof(ConfirmPrompt)));
     services.AddScoped<OAuthPrompt>(_ => new OAuthPrompt(nameof(OAuthPrompt), new OAuthPromptSettings { ConnectionName = "calendarconnection", Title = "Sign In" }));
 . . .
}

LoginDialog.cs

public class LoginDialog : ComponentDialog
{
    public LoginDialog() 
        : base(nameof(LoginDialog))
    {
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            PromptStepAsync,
            LoginStepAsync,
            DisplayTokenPhase1Async,
            DisplayTokenPhase2Async

         }));
    }

    private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)

    {

        return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);

    }
    . . .
}

这里最大的问题是,我已经登录后仍被要求登录。还要注意,第三个OAuth提示是不同的,这就是为什么当我单击它时出现以下错误。 / strong>

代码:InvalidAuthenticationToken 消息:CompactToken解析失败,错误代码:80049217

内部错误

这是代码中发生异常的地方:

MSGraphCalendarAPI.cs

private async Task<List<Event>> GetMyCalendarViewByTime(DateTime startTime, DateTime endTime)
{
      . . .
      try
      {
           events = await _graphClient.Me.CalendarView.Request(options).GetAsync();
      }
      catch (ServiceException ex)
      {
           throw GraphClient.HandleGraphAPIException(ex);
      }
      . . .
}

enter image description here

0 个答案:

没有答案