powered by simpleCommunicator - 2.0.20     © 2024 Programmizd 02
Map
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / net core windows авторизация
19 сообщений из 19, страница 1 из 1
net core windows авторизация
    #40118615
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день. Есть задача при старте приложения получить доменное имя текущего пользователя и как-то вызвать ClaimsLoaderTest чтобы из базы подтянуть настройки, разрешения, фио текущего пользователя.

НО я не знаю как вызвать из Startup ClaimsLoaderTest с текущим пользователем.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
using CustomsWeb.Models;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;

namespace CustomsWeb
{
    public class ClaimsLoaderTest 
    {
        private readonly ApplicationContext Context;

        public ClaimsLoaderTest(ApplicationContext db)
        {
            Context = db;
        }

        public void SetUser(ClaimsPrincipal principal)
        {
            if (principal.Identity is WindowsIdentity identity && (Helpers.CurrentUser == null || Helpers.CurrentUser.DomainName != principal.Identity.Name))
            {
                User User = Context.Users.FirstOrDefault(u => u.DomainName == principal.Identity.Name);

                if (User != null)
                {
                    Helpers.CurrentUser = new User
                    {
                        Id = User.Id,
                        AcsEdIzm = User.AcsEdIzm,
                        AcsTmc = User.AcsTmc,
                        AcsObjects = User.AcsObjects,
                        AcsPoints = User.AcsPoints,
                        AcsAdmin = User.AcsAdmin,
                        AcsGkpzLots = User.AcsGkpzLots,
                        AcsPrice = User.AcsPrice,
                        AcsOffer = User.AcsOffer,
                        FIO = User.FIO,
                        BaseName = User.BaseName,
                        DomainName = principal.Identity.Name
                    };
                }
            }
        }
    }
}



Наверняка это делали многие. Как это делать правильно?
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118616
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ,

запросить экземпляр из контейнера...
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118621
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes
maximIZ,

запросить экземпляр из контейнера...


я тут новичок и не совсем понимаю как это делается. Можно примеры если не трудно. Только пожалуйста не нужно шуток что гугл забанили. Я рою уже не первый день.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118704
Алымов Анатолий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ServiceProvider методы GetService или GetRequiredService
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118808
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в общем вот что получилось

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(IISDefaults.AuthenticationScheme);

            services.AddHttpContextAccessor();

            services.AddSingleton<IUserSetter, UserSetter>();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IUserSetter usr)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            app.UseHttpsRedirection();
            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.Use(async (context, next) =>
            {
                using var serviceScope = app.ApplicationServices.CreateScope();
                var services = serviceScope.ServiceProvider;
                var myDbContext = services.GetService<ApplicationContext>();

                usr.SetUser(myDbContext, context.User);

                await next();
            });

            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
                endpoints.MapDefaultControllerRoute();
                endpoints.MapRazorPages();
            });
        }



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
    public class UserSetter :IUserSetter
    {
        public void SetUser(ApplicationContext Context, ClaimsPrincipal principal)
        {
            if (principal.Identity is WindowsIdentity identity && (Helpers.CurrentUser == null || Helpers.CurrentUser.DomainName != principal.Identity.Name))
            {
                User User = Context.Users.FirstOrDefault(u => u.DomainName == principal.Identity.Name);

                if (User != null)
                {
                    Helpers.CurrentUser = new User
                    {
                        Id = User.Id,
                        AcsEdIzm = User.AcsEdIzm,
                        AcsTmc = User.AcsTmc,
                        AcsObjects = User.AcsObjects,
                        AcsPoints = User.AcsPoints,
                        AcsAdmin = User.AcsAdmin,
                        AcsGkpzLots = User.AcsGkpzLots,
                        AcsPrice = User.AcsPrice,
                        AcsOffer = User.AcsOffer,
                        FIO = User.FIO,
                        BaseName = User.BaseName,
                        DomainName = principal.Identity.Name
                    };
                }
            }
        }
    }


все вроде работает НО. Это нормально когда при открытии каждой страницы срабатывает метод SetUser ? Есть вообще возможность его одинжды при старте вызывать и все!
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118809
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
            app.Use(async (context, next) =>
            {
                using var serviceScope = app.ApplicationServices.CreateScope();
                var services = serviceScope.ServiceProvider;
                var myDbContext = services.GetService<ApplicationContext>();

                usr.SetUser(myDbContext, context.User);

                await next();
            });


Это писец говнокод.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118811
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну так напишите как правильно то. А то критиковать то много ума не надо. Я же писал что я новичок
...
Рейтинг: 0 / 0
net core windows авторизация
    #40118813
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
ну так напишите как правильно то. А то критиковать то много ума не надо. Я же писал что я новичок

Правильно - написать custom middleware, куда передавать ApplicationContext через DI (причем не в конструктор, а как per-request dependency, потому что DbContext, как правило, регистрируется как scoped service). Вот ссылка: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-6.0#per-request-middleware-dependencies.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119456
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пришлось переделать на claims и вот что вышло

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
        public void ConfigureServices(IServiceCollection services)
        {
            string connection = Configuration.GetConnectionString("DefaultConnection");

            services
                .AddDbContext<ApplicationContext>(options => options.UseSqlServer(connection))
                .AddRazorPages(options =>
                {
                    options.Conventions.AuthorizePage("/Index");
                    options.Conventions.AuthorizePage("/EdIzm");
                    options.Conventions.AuthorizePage("/Manufactures");
                })
                .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);

            services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);

            services.AddHttpContextAccessor();

            services.AddScoped<Microsoft.AspNetCore.Authentication.IClaimsTransformation, ClaimsLoader>();
        }



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
    public class ClaimsLoader : IClaimsTransformation
    {
        private readonly ApplicationContext Context;

        public ClaimsLoader(ApplicationContext db)
        {
            Context = db;
        }

        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            if (principal.Identity is WindowsIdentity identity)
            {
                User User = await Context.Users.FirstOrDefaultAsync(u => u.DomainName == principal.Identity.Name);

                if (User != null)
                {
                    var Claims = new List<Claim>
                    {
                        new Claim("Id", User.Id.ToString()),
                        new Claim("AcsEdIzm", User.AcsEdIzm.ToString()),
                        new Claim("AcsTmc", User.AcsTmc.ToString()),
                        new Claim("AcsObjects", User.AcsObjects.ToString()),
                        new Claim("AcsPoints", User.AcsPoints.ToString()),
                        new Claim("AcsAdmin", User.AcsAdmin.ToString()),
                        new Claim("AcsGkpzLots", User.AcsAdmin.ToString()),
                        new Claim("AcsPrice", User.AcsPrice.ToString()),
                        new Claim("AcsOffer", User.AcsOffer.ToString()),
                        new Claim("FIO", User.FIO),
                        new Claim("BaseName", User.BaseName)
                    };

                    identity.AddClaims(Claims);
                }
            }

            return principal;
        }
    }



Проверка пользователя происходит каждый раз при открытии страницы. И каждый раз ломится в базу за получением настроек пользователя. Т.к. клеймы приходят всегда чистые без моих коррекций. Есть ли шанс как-то делать это один раз. Ну или чтобы клеймы приходили не чистые каждый раз. Если делать анонимную идентификацию то там все хранится в кукисах. И не нужно каждый раз обращаться к базе. А при виндоус даже не знаю как правильно все это хранить.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119481
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
Есть ли шанс как-то делать это один раз.

Конечно есть. Если у тебя приложением пользуется только один пользователь.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119528
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat, нет ни один. Если пользуются много доменных пользователей то по другому никак? Каждый раз дергать базу?
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119530
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
fkthat, нет ни один. Если пользуются много доменных пользователей то по другому никак? Каждый раз дергать базу?

Можно дернуть один раз и сохранить в куке. Только тогда надо следить чтобы кука была еще синхронизирована с базой на случай изменений.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119786
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

начинаю играться с кукисами

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
public class UserSetter : IUserSetter
{
    public async Task SetUser(Microsoft.AspNetCore.Http.HttpContext Context)
    {
        if (!Context.Request.Cookies.ContainsKey("BaseName"))
        {
            Context.Response.Cookies.Append("BaseName", "MyTestBase");
        }
    }
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IUserSetter usr)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();

            app.Use(async (context, next) =>
            {
                await usr.SetUser(context);

                await next();
            });

            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
                endpoints.MapDefaultControllerRoute();
                endpoints.MapRazorPages();
            });
        }



и все вроде норм. и из контроллеров можно легко вызывать. НО пытаюсь на странице _Layout.cshtml отобразить данные из кукисов. И при первом старте кукисы показываются пустыми. Но стоит после этого перейти на какую-то станицу кукисы сразу показываются. Вот видео с демонстрацией проблемы https://www.screencast.com/t/o7gsv7xB

Как мне на этой странице добиться отображение кукисов? Возможно создавать кукисы следует не в Configure, а в ConfigureServices ?
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119897
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
ну так напишите как правильно то. А то критиковать то много ума не надо . Я же писал что я новичок


вот именно! Равзелось тут всяких ....
...
Рейтинг: 0 / 0
net core windows авторизация
    #40119952
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
Как мне на этой странице добиться отображение кукисов? Возможно создавать кукисы следует не в Configure, а в ConfigureServices ?

Перемести свой app.Use(...) выше app.UseRouting(...).
...
Рейтинг: 0 / 0
net core windows авторизация
    #40120106
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat, не помогло к сожалению. что может быть еще?
...
Рейтинг: 0 / 0
net core windows авторизация
    #40120112
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
fkthat, не помогло к сожалению. что может быть еще?

В первобытные времена куки добавленные через объект Response сразу становились видны через объект Request (не ожидая повторного запроса). Если в ASP.NET Core это поведение изменилось, то, наверняка, причина в этом. Поставь точку останова на
Код: c#
1.
Context.Response.Cookies.Append("BaseName", "MyTestBase");

и проверь
Код: c#
1.
Context.Request.Cookies.ContainsKey("BaseName")

сразу же после неё.
...
Рейтинг: 0 / 0
net core windows авторизация
    #40120137
maximIZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,
сразу после аппенд Request.Cookies так и остаются пустыми

во тут на видео видно https://www.screencast.com/t/7VGJiwL5W
...
Рейтинг: 0 / 0
net core windows авторизация
    #40120139
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maximIZ
fkthat,
сразу после аппенд Request.Cookies так и остаются пустыми

Отлично. Значит нужен какой-то обходной путь.
Сделай как-нибудь так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
public record User(int Id, string Name);

public interface ICurrentUserAccessor
{
    User? CurrentUser { get; set; }
}

public class CurrentUserAccessor : ICurrentUserAccessor
{
    private const string _cookieName = "UserInfo";

    private readonly IHttpContextAccessor _httpContextAccessor;

    private User? _currentUser;

    public CurrentUserAccessor(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public User? CurrentUser
    {
        get
        {
            if (_currentUser == null)
            {
                var json = _httpContextAccessor.HttpContext?.Request.Cookies[_cookieName];

                if (json != null)
                {
                    _currentUser = JsonSerializer.Deserialize<User>(json);
                }
            }

            return _currentUser;
        }

        set
        {
            _currentUser = value;

            _httpContextAccessor.HttpContext?.Response.Cookies.Append(
                _cookieName, JsonSerializer.Serialize(value));
        }
    }
}

public class Startup
{
    // ....

    public void ConfigureServices(IServiceCollection services)
    {
        // ....

        services.AddHttpContextAccessor();
        services.AddScoped<ICurrentUserAccessor, CurrentUserAccessor>();        

        // ....
    }

    // ....
}



...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / net core windows авторизация
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]