2017-06-19 115 views
0

我正在嘗試構建連接到使用Azure AD身份驗證的企業應用程序的alexa技能。我們在本文中設置了一切,如https://blogs.msdn.microsoft.com/premier_developer/2016/12/12/amazon-alexa-skills-development-with-azure-active-directory-and-asp-net-core-1-0-web-api/,但我在將標記從請求正文移動到標題時遇到問題。 請求通過罰款,我可以解析它,我將標記添加到標題,但在亞馬遜的測試頁上我得到此消息:「有一個錯誤調用遠程端點,它返回HTTP 302:找到」Alexa技能和Azure AD身份驗證

這是添加的令牌發送給報頭的代碼:

public void ConfigureAuth(IAppBuilder app) 
    { 
     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
     app.Use(async (context, next) => 
     { 
      string path = string.Format(ConfigurationManager.AppSettings["ExchangeTraceDrivePath"], "AlexaRequest", DateTime.Now.ToFileTime(), ""); 

      var stream = context.Request.Body; 
      try 
      { 
       using (var buffer = new MemoryStream()) 
       { 
        await stream.CopyToAsync(buffer); 
        var bodyBuffer = new byte[buffer.Length]; 
        buffer.Position = 0L; 
        buffer.Read(bodyBuffer, 0, bodyBuffer.Length); 
        var body = Encoding.UTF8.GetString(bodyBuffer); 
        using (var sw = new StreamWriter(path)) 
        { 
         sw.WriteLine(DateTime.Now.ToString() + " body: " + body); 
         sw.WriteLine("---------------------------------------------------------------------------------------------"); 
         foreach (var header in context.Request.Headers) 
         { 
          sw.WriteLine(DateTime.Now.ToString() + " header key: " + header.Key); 
          foreach (var val in header.Value) 
          { 
           sw.WriteLine(DateTime.Now.ToString() + " header value: " + val); 
          } 
         } 
         sw.WriteLine("---------------------------------------------------------------------------------------------"); 

         dynamic json = JObject.Parse(body); 
         sw.WriteLine(DateTime.Now.ToString() + " parsed body: " + json); 
         sw.WriteLine("---------------------------------------------------------------------------------------------"); 

         if (json?.session?.user?.accessToken != null) 
         { 
          sw.WriteLine(DateTime.Now.ToString() + " access accessToken found " + 
             json?.session?.user?.accessToken); 
          sw.WriteLine("---------------------------------------------------------------------------------------------"); 

          context.Request.Headers.Add("Authorization", 
           new string[] { string.Format("Bearer {0}", json?.session?.user?.accessToken) }); 
          foreach (var header in context.Request.Headers) 
          { 
           sw.WriteLine(DateTime.Now.ToString() + " header key: " + header.Key); 
           foreach (var val in header.Value) 
           { 
            sw.WriteLine(DateTime.Now.ToString() + " header value: " + val); 
           } 
          } 
          sw.WriteLine("---------------------------------------------------------------------------------------------"); 
         } 
         buffer.Position = 0L; 
         context.Request.Body = buffer; 
        } 
       } 
      } 
      catch 
      { 
      } 
      finally 
      { 
       await next.Invoke(); 
       // Restore the original stream. 
       context.Request.Body = stream; 
      } 

     }); 

     //ExpireTimeSpan and SlidinExpiration only work when UseTokenLifetime = false 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      // This is NOT ASP.NET Session Timeout (that should be set to same value in web.config) 
      // This is the expiration on the cookie that holds the Azure AD token 
      ExpireTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(expirationTimeSpan)), 

      // Set SlidingExpiration=true to instruct the middleware to re-issue a new cookie 
      // with a new expiration time any time it processes a request which is more than 
      // halfway through the expiration window. 
      SlidingExpiration = true, 

      Provider = new CookieAuthenticationProvider 
      { 
       // This method is called every time the cookie is authenticated, which 
       // is every time a request is made to the web app 
       OnValidateIdentity = CookieAuthNotification.OnValidateIdentity 
      } 
     }); 

     app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions 
      { 
       ClientId = clientId, 
       Authority = authority, 
       UseTokenLifetime = false, 
       /* 
       * Skipping the Home Realm Discovery Page in Azure AD 
       * http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/ 
       */ 
       Notifications = new OpenIdConnectAuthenticationNotifications 
       { 
        RedirectToIdentityProvider = OpenIdConnectNotification.RedirectToIdentityProvider, 
        MessageReceived = OpenIdConnectNotification.MessageReceived, 
        SecurityTokenReceived = OpenIdConnectNotification.SecurityTokenReceived, 
        SecurityTokenValidated = OpenIdConnectNotification.SecurityTokenValidated, 
        AuthorizationCodeReceived = OpenIdConnectNotification.AuthorizationCodeReceived, 
        AuthenticationFailed = OpenIdConnectNotification.AuthenticationFailed 
       }, 

      }); 
    } 
+0

你介意共享302重定向的地址嗎?你配置了[認證/授權](https://docs.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-how-to-configure-active-directory-authentication ?toc =%2fazure%2fapp-service%2ftoc.json)用於部署在Azure上的Web API? –

+0

該文章中的哪個設置是執行302重定向的網址? Web API實際上是一個MVC應用程序,我在其中添加了一個控制器來處理alexa電話。該應用程序是在幾年前配置的,並且在alexa中鏈接的用戶可以在Web應用程序中完全登錄。 –

+0

無法確定沒有附加信息的根本原因。您可以分享地址重定向,並查看是否有人可以提供有用的建議。 –

回答

0

我結束了創建一個單獨的中間件令牌從所述主體移動到頭部

public class AlexaJWTMiddleware : OwinMiddleware 
{ 
    private readonly OwinMiddleware _next; 

    public AlexaJWTMiddleware(OwinMiddleware next) : base(next) 
    { 
     _next = next; 
    } 


    public override Task Invoke(IOwinContext context) 
    { 
     var stream = context.Request.Body; 
     if (context.Request.Headers.ContainsKey("SignatureCertChainUrl") 
      && context.Request.Headers["SignatureCertChainUrl"] 
       .Contains("https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem") 
      && !context.Request.Headers.ContainsKey("Authorization")) 
     { 

      try 
      { 
       using (var buffer = new MemoryStream()) 
       { 
        stream.CopyToAsync(buffer); 
        var bodyBuffer = new byte[buffer.Length]; 
        buffer.Position = 0L; 
        buffer.Read(bodyBuffer, 0, bodyBuffer.Length); 
        var body = Encoding.UTF8.GetString(bodyBuffer); 

        dynamic json = JObject.Parse(body); 
        if (json?.session?.user?.accessToken != null) 
        { 

         context.Request.Headers.Add("Authorization", 
          new string[] { string.Format("Bearer {0}", json?.session?.user?.accessToken) }); 
        } 
        buffer.Position = 0L; 
        context.Request.Body = buffer; 
       } 
      } 
      catch 
      { 
      } 
      finally 
      { 
       // Restore the original stream. 
       context.Request.Body = stream; 
      } 
     } 
     else 
     { 
      return _next.Invoke(context); 

     } 
     return _next.Invoke(context); 

    } 
} 

,然後加入JWT認證除了openId之外

public void ConfigureAuth(IAppBuilder app) 
    { 
     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
     app.Use(typeof(AlexaJWTMiddleware)); 
     app.UseWindowsAzureActiveDirectoryBearerAuthentication(
      new WindowsAzureActiveDirectoryBearerAuthenticationOptions 
      { 
       Tenant = domain, 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        ValidAudience = ConfigurationManager.AppSettings["ida:AppIdUri"] 
       }, 
       AuthenticationType = "OAuth2Bearer", 
      }); 

     //ExpireTimeSpan and SlidinExpiration only work when UseTokenLifetime = false 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      // This is NOT ASP.NET Session Timeout (that should be set to same value in web.config) 
      // This is the expiration on the cookie that holds the Azure AD token 
      ExpireTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(expirationTimeSpan)), 

      // Set SlidingExpiration=true to instruct the middleware to re-issue a new cookie 
      // with a new expiration time any time it processes a request which is more than 
      // halfway through the expiration window. 
      SlidingExpiration = true, 

      Provider = new CookieAuthenticationProvider 
      { 
       // This method is called every time the cookie is authenticated, which 
       // is every time a request is made to the web app 
       OnValidateIdentity = CookieAuthNotification.OnValidateIdentity 
      } 
     }); 

     app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions 
      { 
       ClientId = clientId, 
       Authority = authority, 
       UseTokenLifetime = false, 
       /* 
       * Skipping the Home Realm Discovery Page in Azure AD 
       * http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/ 
       */ 
       Notifications = new OpenIdConnectAuthenticationNotifications 
       { 
        RedirectToIdentityProvider = OpenIdConnectNotification.RedirectToIdentityProvider, 
        MessageReceived = OpenIdConnectNotification.MessageReceived, 
        SecurityTokenReceived = OpenIdConnectNotification.SecurityTokenReceived, 
        SecurityTokenValidated = OpenIdConnectNotification.SecurityTokenValidated, 
        AuthorizationCodeReceived = OpenIdConnectNotification.AuthorizationCodeReceived, 
        AuthenticationFailed = OpenIdConnectNotification.AuthenticationFailed 
       }, 

      }); 
    }