9

如果您處於控制器上下文中,則可以訪問當前經過身份驗證的用戶。拿一篇文章,如Get the current user, within an ApiController action, without passing the userID as a parameter如何在Web API的服務上下文中訪問用戶?

但是,如果我的控制器調用一個服務(相同的程序集),但在這裏我沒有控制器上下文。

真正獲得經過身份驗證的用戶的最佳方式是什麼?

+1

從什麼能當前認證的用戶進入你的服務停止你的當前HttpContext出方的東西IHttpContextAccessor? –

+0

@KirkLarkin使我的方法簽名非常可惡。似乎並不乾淨。並且讓我們說你想公開API並允許它沒有一個真正的客戶使用它,那麼它不是很乾淨。 –

+0

在這種情況下,似乎您的問題可能更多地是關於如何處理可選身份驗證,而不是ASP.NET Web API的具體細節。只要你有能力只有時有一個用戶,有一個服務,自動檢測是否有用戶或只是有一個通過可能不會有很大的不同。 –

回答

7

您可以創建一箇中間服務,以提供該功能

public interface IPrincipalProvider { 
    IPrincipal User { get; } 
} 

public class WebApiPrincipalProvider : IPrincipalProvider { 
    public IPrincipal User { 
     get { 
      return HttpContext.Current != null 
       ? HttpContext.Current.User 
       : null; 
     } 
    } 
} 

,並注入到依賴服務上下文

public class MyService : IService { 
    private readonly IPrincipalProvider provider; 

    public MyService(IPrincipalProvider provider) { 
     this.provider = provider; 
    } 

    public MyModel MyServiceMethod() { 
     var currentUser = provider.User; 
     var name = currentUser.Identity.Name; 

     //...use user.... 

     return model; 
    } 
} 

最後確保抽象和實施與DI容器組成根註冊的主應用程序,這樣當服務注入控制器時,它也能夠訪問當前請求的用戶。

[Authorize] 
public class MyController : ApiController { 
    public readonly IService service; 

    public MyController (IService service) { 
     this.service = service; 
    } 

    [HttpGet] 
    public IHttpActionResult MyGetActiom() { 
     var model = service.MyServiceMethod(); 
     return Ok(model); 
    } 
} 

當Identity框架對用戶進行身份驗證時,會爲當前上下文設置用戶主體。

如果託管在IIS中,您可以點擊HttpContext來訪問用戶,就像之前提供的示例一樣。 MVC和Web API基本上做了類似的工作,填入Controller.UserApiController.User

如果自主託管有其他方式訪問它。

事實是,一旦通過驗證,用戶就可以使用。將其封裝在抽象之後,並且可以將其注入任何需要控制器以外的地方。

Asp.net的核心引入了類似於這使得服務類訪問控制器

public interface IHttpContextAccessor { 
    HttpContext HttpContext { get; } 
} 
+0

啊,現在我明白了。非常感謝 - 它也有效;-)!冷卻時間結束後,我會在5個小時內獎勵賞金! –

相關問題