Как получить доступ к текущему пользователю в определенном аспекте - PullRequest
0 голосов
/ 14 октября 2018

Если я принял последний сценарий в этом тезисе :

enter image description here

Тогда мои основные слои будут такими:

  • Служба пользовательского интерфейса (приложение 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");
        }
    } 

Я хочу установить текущего пользователя во время выполнения.


  • Какполучить доступ к текущему пользователю, чтобы авторизовать его для определенной функциональности на бизнес-уровне?
  • Должна ли авторизация быть ближе к интерфейсу пользователя, чтобы отключить / скрыть функциональность и предотвратить вызов недопустимых методов действия? (В предпочтительном сценариинет никакого взаимодействия между уровнем безопасности и пользовательским интерфейсом !!)

Ответы [ 3 ]

0 голосов
/ 19 октября 2018

Как получить доступ к текущему пользователю, чтобы авторизовать его для определенной функции на бизнес-уровне?

Чтобы получить доступ к информации о пользователе на бизнес-уровне, вы можете ввести интерфейс с именем 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>();
        }
    }
}

пользовательская информация записывается в HttpContext с классом ContextHelper, и для этого используется правильный класс перехватчика местоположения

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 уникален для каждого запроса и ответа

Должна ли авторизация быть ближе к интерфейсу пользователя, чтобы отключить / скрыть функциональность и предотвратить вызов недопустимых методов действия? (В предпочтительном сценарии нет никакого взаимодействия междууровень безопасности и пользовательский интерфейс !!)

Это ваш выбор

По моему мнению, вы можете использовать пользовательские привилегии и регистрировать их с помощью кэша и использовать их для действий на стороне клиента, нов соответствии с технологией, которую вы используете для серверной части, вы можете хранить информацию о пользователях для каждого запроса аналогичным образом.Например;Правильное расположение для хранения OperationContext для wcf.

0 голосов
/ 22 октября 2018

Обновление

Пожалуйста, смотрите этот ответ об использовании утверждений ...


В контроллере вы можете получить текущего пользователя, как этот:

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.

Если у вас есть доступ к HttpContext, вы можете получить пользователя следующим образом:

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

Если вы хотите, чтобы ApplicationUser использовал это ( больше информацииздесь ):

// 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 , уже выполняет задачу авторизации для вас.Это реализовано в ApplicationUserManager и ApplicationSignInManager, которые поставляются с шаблоном ASP.NET MVC по умолчанию.Вы можете использовать атрибут [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, посмотрите на эту эту ссылку , которая объясняет службы, которыепринадлежат каждому слою.

0 голосов
/ 17 октября 2018

Если вы используете ASP.NET Identity, вы можете попробовать следующий подход для получения текущего пользователя:

ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

//If you use int instead of string for primary key, use this:
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(Convert.ToInt32(System.Web.HttpContext.Current.User.Identity.GetUserId()));

Надеюсь, это поможет ...

...