2016-10-07 43 views

回答

1

如果我正确理解您的问题,您希望将授权令牌从一个Web API服务转发到另一个Web API?

这是我做的:

  • 创建请求上下文中存在的会话环境。这是通过使用Unity和HierarchicalLifetimeManager完成的。
  • 从请求中提取所有头在app-a,并把它放到会话的上下文
  • 使用HttpClient调用app-b之前插入的cookie。

如果你想,你也可以只提取令牌而不是所有的cookie。

SessionContext

public class SessionContext 
{ 
    public string Token { get; private set; } 
    public CookieHeaderValue Cookies { get; private set; } 
    public void SetToken(string token) 
    { 
     if(Token != null) 
      throw new InvalidOperationException("Token is already set in this session."); 

     Token = token; 
    } 

    public void SetCookies(CookieHeaderValue cookies) 
    { 
     if (Cookies != null) 
      throw new InvalidOperationException("Cookies is already set in this session."); 
     Cookies = cookies; 
    } 
} 

CookieFetcher

/// <summary> ActionFilter to extract all cookie and add it to the <see cref="SessionContext"/>. </summary> 
public class CookieFetcherAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var cookies = actionContext.Request.Headers.GetCookies().SingleOrDefault(); 

     if (cookies == null) 
      return; 

     var sessionContext = actionContext.Request.GetDependencyScope().GetService<SessionContext>(); 
     sessionContext.SetCookies(cookies); 
    } 
} 

统一配置

// Gets a new TokenProvider per request 
container.RegisterType<SessionContext>(new HierarchicalLifetimeManager()); 

客户端

public class Client 
{ 
    private CookieHeaderValue Cookies => sessionContext.Cookies; 

    public Client(SessionContext sessionContext) 
    { 
     this.sessionContext = sessionContext; 
    } 

    private HttpClient CreateHttpClient() 
    { 
     // If cookie/sessionId based authentication is used. 
     if (Cookies != null) 
     { 
      handler.CookieContainer = ConvertToCookieContainer(Cookies, baseUri.GetRootHostName()); 
      handler.UseCookies = true; 
     } 

     var client = new HttpClient(handler, true); 
     client.BaseAddress = baseUri; 

     return client; 
    } 

    private static CookieContainer ConvertToCookieContainer(CookieHeaderValue cookies, string cookiePath) 
    { 
     var container = new CookieContainer(); 
     foreach (var cookie in cookies.Cookies) 
     { 
      container.Add(new Cookie(cookie.Name, cookie.Value, "/", cookiePath)); 
     } 
     return container; 
    } 
}