如何在特定方面访问当前用户

时间:2018-10-14 14:55:04

标签: asp.net-mvc asp.net-identity domain-driven-design aop postsharp

如果我在此thesis中采用了最后一个方案:

enter image description here

然后我的主要图层将是这样:

  • UI服务(MVC应用程序)
  • 业务层
  • 安全服务(用作MS身份的包装类库) 框架)
  • 使用先前的安全服务来授权的方面 业务层方法。

 public class EditEmployeeData : OnMethodBoundaryAspect
    {

        public override void OnEntry(MethodExecutionArgs args)
        {
            Employee emp = (Employee)args.Instance;
            ((System.Security.Claims.ClaimsIdentity)System.Web.HttpContext.Current.User.Identity).HasClaim("Employee", "EditName");
        }
    } 

我想在运行时设置当前用户。


  • 如何访问当前用户以授权特定用户 业务层的功能?
  • 授权是否应该更接近UI以禁用/隐藏功能并防止调用不允许的操作方法?(在首选方案中,安全层和UI之间没有任何交互!)

3 个答案:

答案 0 :(得分:2)

更新

有关使用声明的信息,请参见this answer ...


在控制器中,您可以像这样获得当前用户:

using Microsoft.AspNet.Identity.Owin;

public class MyController : Controller
{
    // this code will return 0 if user is not authenticated
    protected long GetUserId()
    {
       // note: I have changed the default UserId type from Guid to long
       return User.Identity.GetUserId<long>(); 

       /* 
        * use this if you are using Guid UserIds (which is the default)     
        * return User.Identity.GetUserId();
        */
    }

如果想知道如何更改UserId的类型,请参见this

如果您有权访问HttpContext,则可以这样获得用户:

// note that I have changed UserId from Guid to long
HttpContext.Current.User.Identity.GetUserId<long>()

如果要获取ApplicationUser,请使用此more info here):

// this is how you get user manager from OwinContext    
var userManager = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
// Get ApplicationUser from UserManager 
ApplicationUser user = UserManager.FindById(User.Identity.GetUserId());

  

如何访问当前用户以授权特定用户   业务层的功能?

如果您需要访问服务中的当前用户,则可以通过它,也可以注入。使用 ninject ,这是将UserId注入服务的方式:

kernel.Bind<MyService>().ToConstructor(ctorArg => new MyService(
            HttpContext.Current.User.Identity.GetUserId<long>()).InRequestScope(); 

这是MyService类的样子:

public class MyService
{
    private readonly long _userId;

    public MyService(long userId)
    {
       // this service always has access to current user (if logged in)
        _userId = userId;
    }
    // more code...

我不确定您的授权过程是什么... ASP.NET Identity 已经为您实现了授权任务。这是在ASP.NET MVC默认模板随附的ApplicationUserManagerApplicationSignInManager中实现的。您可以在操作/类上使用[Authorize]属性来防止未经授权的访问:

[Authorize] // <-- restricts all action methods of the class, unless marked [AllowAnonymous]
public class MyController : Controller
{
    [HttpPost]
    [Authorize] // <-- restricts this particular action method
    public ActionResult MyAction(long id)
    {
       // do some action which requires authorization
    }

关于DDD层,请看一下this link,它解释了属于每个层的服务。

答案 1 :(得分:1)

如何访问当前用户以授权他使用业务层中的特定功能?

要访问业务层上的用户信息,可以键入一个名为ICurrentUser的接口

namespace AOPSample
{
    public interface ICurrentUser
    {
        User GetCurrentUser();
    }

    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Role { get; set; }
    }
}

CurrentUser类必须能够从公共位置读取用户的信息。 HttpContext可用于此。

让我们为此编写一个帮助器类。

using System.Web;

namespace AOPSample
{
    public class ContextHelper
    {
        public T Get<T>()
        {
            T local = default(T);
            string key = typeof(T).GUID.ToString();
            if (HttpContext.Current.Items.Contains(key))
            {
                local = (T)HttpContext.Current.Items[key];
            }
            return local;
        }

        public T Get<T>(string key)
        {
            T local = default(T);
            if (HttpContext.Current.Items.Contains(key))
            {
                local = (T)HttpContext.Current.Items[key];
            }
            return local;
        }

        public void Set<T>(T value)
        {
            string str = typeof(T).GUID.ToString();
            HttpContext.Current.Items[str] = value;
        }

        public void Set<T>(T value, string key)
        {
            HttpContext.Current.Items[key] = value;
        }
    }
}

我们的CurrentUser类将使用您的助手类返回用户信息

namespace AOPSample
{
    public class CurrentUser : ICurrentUser
    {
        public User GetCurrentUser()
        {
            return new ContextHelper().Get<User>();
        }
    }
}

现在用户信息已使用ContextHelper类写入HttpContext,为此使用正确的位置拦截器类

public class EditEmployeeData : OnMethodBoundaryAspect
    {

        public override void OnEntry(MethodExecutionArgs args)
        {
            Employee emp = (Employee)args.Instance;
            ((System.Security.Claims.ClaimsIdentity)System.Web.HttpContext.Current.User.Identity).HasClaim("Employee", "EditName");

            new ContextHelper().Set<User>(new User
            {

            });
        }
    } 

您可以使用ICurrentUser从域层访问用户信息。 HttpContext对于每个请求和响应都是唯一的

授权是否应该更靠近UI以禁用/隐藏功能并防止调用不允许的操作方法?(在首选方案中,安全层与UI之间没有任何交互!)

这是您的选择

我认为,您可以获取用户特权并使用缓存对其进行登录,并将其用于客户端操作,但是根据用于服务器端的技术,您可以类似的方式存储每个请求的用户信息。例如;存储用于wcf的OperationContext的正确位置。

答案 2 :(得分:0)

如果您使用Long,则可以尝试以下方法来获取当前用户:

ASP.NET Identity

希望这对您有帮助...