GetUserDataAsync 从连接器客户端引发"Access Denied"错误



更新1整个登录控制器现在都在代码段中。

更新2现已修复。问题是,我使用模拟器运行机器人程序,连接器客户端不喜欢它。ConnectorClient在托管机器人程序时生成了一个用户ID,而这个用户ID与模拟器生成的用户ID不匹配。因此,访问被拒绝。长话短说,机器人程序必须托管,并且应该使用连接器客户端接受您请求的有效通道之一进行访问。希望它能帮助其他人。

更新3修复了Vish api路由中的一个小错误

我一直在尝试为一个应用程序设置oauth流。我已经设法从服务中获得了userInfo,但无法将访问令牌与机器人的userid绑定。

public class LoginController : ApiController
{
    [HttpGet, Route("api/login")]
    public RedirectResult Login(string userid)
    {
        return Redirect(String.Format("https://login.windows.net/microsoft.com/oauth2/authorize?response_type=code&client_id={0}&redirect_uri={1}&resource={2}&state={3}",
            "MyClientId",  HttpUtility.UrlEncode(Constants.apiBasePath + userid + "/authorize"),HttpUtility.UrlEncode('MyService'), userid));
    }
    [HttpGet, Route("api/authorize")]
    public async System.Threading.Tasks.Task<HttpResponseMessage> Authorize(string state, string code)
    {
        string userid = state;
        AuthenticationContext ac = new AuthenticationContext("https://login.windows.net/microsoft.com/oauth2/authorize/");
        ClientCredential cc = new ClientCredential("MyClientId", "MyClientSecret");
        AuthenticationResult ar = await ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri(Constants.apiBasePath + userid + "/authorize"), cc);
        if (!String.IsNullOrEmpty(ar.AccessToken))
        {
            var client = new ConnectorClient(Constants.botId,Constants.botSecret);
            var getData = await client.Bots.GetUserDataAsync(Constants.botId, userid);
            getData.Data = ar.Serialize();
            var foo = await client.Bots.SetUserDataAsync(Constants.botId, userid, getData);
            //return Request.CreateResponse(foo);
            var response = Request.CreateResponse(HttpStatusCode.Moved);
            response.Headers.Location = new Uri("/loggedin.htm", UriKind.Relative);
            return response;

        }
        else
            return Request.CreateResponse(HttpStatusCode.Unauthorized);
    }

在上面的代码段中,成功生成了包含所有必需数据的身份验证结果"ar"。现在,在以下几行中,我无法从GetUserDataAsync函数获取userData对象。它总是抛出以下错误。

{
  "message": "An error has occurred.",
  "exceptionMessage": "Access Denied",
  "exceptionType": "Microsoft.Rest.HttpOperationException",
  "stackTrace": "   at Microsoft.Bot.Connector.ErrorHandling.HandleError[ObjectT]
}

我认为您需要遵循FacebookAuthSample中显示的ResumptionCookie方法。在该示例中,您将看到令牌存储在对话框中,而不是Web API中。

此外,您可以尝试以以下方式实例化客户端

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
     var client = scope.Resolve<IConnectorClient>();
     client.Messages.SendMessage(message);
}

更新:现在已修复。问题是我也在Azure Portal中配置了身份验证,这在上下文中是不需要的。这导致了额外的一层所需身份验证,阻止用户访问Slack等渠道上的机器人。当我在Azure门户中删除身份验证时,机器人开始工作,我可以通过代码使用Azure AD进行身份验证。

我无法添加评论(需要50名代表),所以在这里发布我的问题。将在一段时间内删除。

@ManikantaReddy,我遵循的是相同的样本,但在实现这一点时遇到了不同的问题。当我试图点击链接获得授权时,我一直在获得401未授权。我的MessagesController.cs看起来像这样:

        try
        {
            string d = (string)message.BotUserData;
            AuthenticationResult ar = AuthenticationResult.Deserialize(d);
            AuthenticationContext ac = new AuthenticationContext("https://login.windows.net/common/oauth2/authorize/");
            ar = DateTimeOffset.Compare(DateTimeOffset.Now, ar.ExpiresOn) < 0 ? ar : await ac.AcquireTokenByRefreshTokenAsync(ar.RefreshToken, new ClientCredential(Constants.ADClientId, Constants.ADClientSecret));
        }
        catch (Exception ex)
        {
            return message.CreateReplyMessage($"You must authenticate to use bot: https://mybot.azurewebsites.net/api/{message.From.Id}/login");
        }

我的登录内容看起来和你的一模一样。我是不是错过了什么?

相关内容

最新更新