gpt4 book ai didi

c# - 可选注入(inject)当前用户的最佳实践

转载 作者:太空狗 更新时间:2023-10-30 01:05:46 26 4
gpt4 key购买 nike

在我们的 ASP.NET MVC 项目中,我们使用 Ninject 来解决 Controller 所需的依赖关系。

其中一个依赖项是当前用户 HttpContext.Current.User.Identity。如果用户通过了身份验证,我们想实例化一个用户对象和依赖它的几个服务。但我们不想手动执行此操作,而是让 ninject 将这些实例注入(inject) Controller 。

所以我们现在遇到麻烦了,因为当然可以在不经过身份验证的情况下找到 url。然后 ninject 在 asp.net 可以重定向到登录页面之前尝试解析实例。

我可以想到解决方案,我们配置 ninject 只在用户通过身份验证时注入(inject):

kernel.Bind<User>().ToMethod(GetUser).When(context => HttpContext.Current.User.Identity.IsAuthenticated).InRequestScope();

这里的问题是,即使用户未通过身份验证,ninject 也会实例化一个默认对象,所以我的服务崩溃或无论如何都需要检查实例。空检查会让我更容易接受,但我不想激活 Ninject 的 AllowNullInjection 设置。

所以我的问题是做这种有条件的事情的最佳实践是什么?在这些情况下是否可以使用 Ninject 功能,或者我是否应该注入(inject)这些依赖项?

最佳答案

我假设您正在谈论一种情况,即未经身份验证的用户可能会尝试导航到通常需要身份验证的页面,但无需先完成登录过程。 Ninject 将无法将当前用户对象注入(inject)到 Controller 中,因为它尚不清楚并将抛出异常。

我可以看到 2 个选项:

第一个选项不是注入(inject)当前用户,而是创建一个工厂或 provider检索当前用户详细信息并将其注入(inject)。然后 Controller 可以调用提供者来获取当前用户,如果用户不可用,您可以重定向到登录页面。

public OrdersController(IUserProvider userProvider)
{
this.userProvider = userProvider
}

public void DoSomething()
{
var user = this.userProvider.GetCurrentUser();
if (user == null)
RedirectToLogin();

// continue doing something
}

public class UserProvider : IUserProvider
{
public User GetCurrentUser() { ... }
}

此选项的问题是您可能需要在许多 Controller 中执行此操作(这是一个“横切关注点”),并且您不想一遍又一遍地重复执行重定向的代码。相反,第二种选择是使用 Decorator 设计模式创建一个拦截器,在转发到实际 Controller 之前检查登录用户。

我过去做类似事情的方法是使用 Ninject Interception Extension创建一个标记哪些 Controller 需要身份验证的属性,如下所示(位伪代码):

public class AuthenticationInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
bool authenticated = // ... get the current user ...

if (authenticated)
invocation.Proceed();
else
RedirectToLoginPage(); // however you want to do this
}
}

public class RequiresAuthenticationAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Context.Kernel.Get<AuthenticationInterceptor>();
}
}

[RequiresAuthentication]
public class OrdersController : IOrdersController
{
// assume you've already been authenticated
}

每当创建一个用 RequiresAuthentication 修饰的类并检查当前用户凭据时,拦截器就会自动创建。如果它们无效,请求将被转发到登录页面,否则它将照常继续。这个拦截器可以一次编写和测试,同时在许多地方使用,而无需重复代码。

关于c# - 可选注入(inject)当前用户的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17427199/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com