Страницы

Поиск по вопросам

Показаны сообщения с ярлыком asp.net-identity-2. Показать все сообщения
Показаны сообщения с ярлыком asp.net-identity-2. Показать все сообщения

пятница, 13 марта 2020 г.

Внедрение зависимостей в Owin

#aspnet_mvc #dependency_injection #aspnet_identity_2 #owin


В базовом шаблоне при создании asp.net mvc проекта в качестве системы авторизации
(по умолчанию) используется asp.net identity.

public class ApplicationUser : IdentityUser
{
    public async Task GenerateUserIdentityAsync(
        UserManager manager)
    {}
}

public class ApplicationUserManager : UserManager
{
    public ApplicationUserManager(IUserStore store)
        : base(store)
    {}

    public static ApplicationUserManager Create(
        IdentityFactoryOptions options,
        IOwinContext context)
    {}
}

public class ApplicationSignInManager : SignInManager
{
    public ApplicationSignInManager(
        ApplicationUserManager userManager,
        IAuthenticationManager authenticationManager) : 
        base(userManager, authenticationManager) { }

    public override Task CreateUserIdentityAsync(ApplicationUser user)
    {}

    public static ApplicationSignInManager Create(
        IdentityFactoryOptions options,
        IOwinContext context)
    {}
}

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {}

    static ApplicationDbContext()
    {}

    public static ApplicationDbContext Create()
    {}
}


Указанные выше классы используются при настройки авторизации в приложении

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and role manager to use
        // a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext(ApplicationUserManager.Create);
        app.CreatePerOwinContext(ApplicationRoleManager.Create);
        app.CreatePerOwinContext(ApplicationSignInManager.Create);

    }
}


Как в приведенном коде избавиться от сильной зависимости - app.CreatePerOwinContext()?
    


Ответы

Ответ 1



Воспользуемся IoC контейнером Autofac для внедрения зависимостей. При помощи менеджера пакетов Nuget установим необходимые пакеты: Autofac Autofac ASP.NET MVC 5 Integration Autofac OWIN Integration Внесем следующие изменения в класс Startup: private void ConfigureContainer(IAppBuilder app) { var builder = new ContainerBuilder(); // STANDARD MVC SETUP: // Register your MVC controllers. builder.RegisterControllers(typeof(MvcApplication).Assembly); // Run other optional steps, like registering model binders, // web abstractions, etc., then set the dependency resolver // to be Autofac. builder.RegisterType().As().InstancePerRequest(); builder.RegisterType() .As>().InstancePerRequest(); builder.RegisterType>() .As>().InstancePerRequest(); builder.Register((c, p) => c.Resolve() .Authentication).InstancePerRequest(); var dataProtectionProvider = app.GetDataProtectionProvider(); builder.Register>((c, p) => BuildUserManager(c, p, dataProtectionProvider)); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // OWIN MVC SETUP: // Register the Autofac middleware FIRST, then the Autofac MVC middleware. app.UseAutofacMiddleware(container); app.UseAutofacMvc(); } private UserManager BuildUserManager( IComponentContext context, IEnumerable parameters, IDataProtectionProvider dataProtectionProvider) { var manager = new ApplicationUserManager(context.Resolve>()); // Configure validation logic for usernames manager.UserValidator = new UserValidator(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; // Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; // Register two factor authentication providers. // This application uses Phone and Emails as a step of receiving a code // for verifying the user // You can write your own provider and plug it in here. manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider { MessageFormat = "Your security code is {0}" }); manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider { Subject = "Security Code", BodyFormat = "Your security code is {0}" }); //manager.EmailService = new EmailService(); //manager.SmsService = new SmsService(); if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider( dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } Добавим вызов метода ConfigureContainer(IAppBuilder app) в метод Configuration(IAppBuilder app) public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); ConfigureContainer(app); } } После выше приведенных действий можно удалить методы app.CreatePerOwinContext() из метода ConfigureAuth() так же необходимо модифицировать AccountControlle, ManageController: Убрать конструктор без параметров. Удалить следующие свойства: UserManager, SignInManager, AuthenticationManager Вот так может выглядеть AccountController после внесения необходимых изменений: public class AccountController : Controller { private readonly IAuthenticationManager _authenticationManager; private readonly SignInManager _signInManager; private readonly UserManager _userManager; public AccountController( UserManager userManager, SignInManager signInManager, IAuthenticationManager authenticationManager) { _authenticationManager = authenticationManager; _userManager = userManager; _signInManager = signInManager; } //Прочие необходимые методы } Использованные источники информации: Autofac’s documentation Habrahabr

Ответ 2



Строка app.CreatePerOwinContext(ApplicationUserManager.Create); нужна фреймворку для того чтобы можно было получть объект ApplicationUserManager в SecurityStampValidator. Не обязательно оставлять код для ApplicationUserManager.Create но нужно научить фреймворк как получать инстанс ApplicationUserManager. Если используется DI контейнер, то можно будет заменать на app.CreatePerOwinContext(() => DependencyResolver.Current.GetService());

понедельник, 6 января 2020 г.

Как узнать на сайте ли пользователь или нет?

#aspnet_mvc #aspnet #asp #aspnet_identity_2


То есть как в вк:  проверяется на сайте ли пользователь, и потом пишет.
И мне интересно как это делается. Знает ли кто эту страшную тайну?
    


Ответы

Ответ 1



В случае VK, если говорить про почту, используется Long Polling, отправляются запросы на imxxx и al_im.php. Т.е, если неплохая достаточно точность нужна, то клиент должен пинговать сервак периодически. Если точность особо не важна, то можно запоминать последнее время, когда человек заходил на сайт или когда посылал к серваку последний запрос. Это и будет, по сути, временем, когда человек последний раз был онлайн.

понедельник, 30 декабря 2019 г.

ASP.NET Identity VS Самописная система авторизации

#c_sharp #aspnet #aspnet_mvc #oauth2 #aspnet_identity_2


Может показаться что это очень "холиварный" вопрос, но я всё же задам его.

Начинал писать свою систему ещё тогда, когда был в моде ASP.NET Membership. Ну естественно,
гибкости мне далеко не хватало и я решил писать свою систему авторизации, не опираясь
на какие-то устоявшиеся в те времена принципы разработки авторизационных/аутентификационных
систем. Что примерно из себя напоминает система сейчас:


Отдельный контекст (мало ли что в жизни бывает);
CodeFirst - реализация;
Хранение токена сессии в кукисах и сравнение его с токеном в отдельной таблице в БД.
Авторизационные фильтры типа ([IdentityFilter("admin", "user", "manager")]) и типа
([IdentityFilter(RolesEnum.Manager)]). На выбор ;)
Репозиторий.
Авторизационная информация получается в фильтре и далее гуляет в HttpContext`e.
Ну и много других мелочей.


Так вот, как бы работает быстро, но что то подсказывает мне, что можно ещё быстрее. 

Собственно хотелось узнать, какие преимущества может нести для меня Identity и целесообразно
ли его использование в "реальном продакшне", или же это интерфейс для новичков, и для
тех, кто не хочет парится.

Ведь в моём коде для меня нет никаких ограничений, а вот в Identity ограничения всё
таки есть, хотя бы то же самое именование таблиц и полей по умолчанию.

P.S. Прошу очень развёрнутый, и тем более аргументированный ответ. Заранее спасибо!
    


Ответы

Ответ 1



Membership забыл как страшный сон, перешел на Identity: Нужна простая авторизация без лишней возни? - пожалуйста. Добавил подсистему и забыл. Нужно использовать Claims? - пожалуйста. Не нужно? - можно добавить в любой момент, а до тех пор хранить все основной таблице. А Claims так и будет ждать своего часа. Нужно добавить авторизацию через соцсети? - пожалуйста. Не нравятся именование полей или самой таблицы? - можно все переименовать. Нужно добавить новое поле? - пожалуйста. Автоматическая миграция, ничего не нужно удалять или бэкапить. Необходима двухфакторная аутентификация с подтверждением по смс или электронной почте? - Всё есть, просто добавить необходимые службы. Дополнительные требования к логинам и паролям? - орудия пыток на выбор: AllowOnlyAlphanumericUserNames, RequireUniqueEmail // ------------------- RequiredLength = 6, RequireNonLetterOrDigit = false, RequireDigit = false, RequireLowercase = false, RequireUppercase = false и т.д. и т.п. Проще в студии загрузить готовый шаблон и поковырять его пару вечерков, чтобы точно убедиться подходит ли Identity для своих нужд. Для загрузки рабочего примера с комментариями в консоли пишем «Install-Package Microsoft.AspNet.Identity.Samples -Pre» Update Если нужно простое, гибкое, функциональное и готовое решение - Asp.net Identity подойдет. Все в коробке. Если необходимо реализовывать сложные сценарии: глубокие политики безопасности, одновременная аутентификация по Active Directory, сертификатам, токенам, онлайн формам (как на всех сайтах), то советую обратить внимание на Windows Identity Foundation. Придется несколько попотеть.

Ответ 2



Холивар полнейшей -) Добавлю к ответу от товарища @Ice2burn - авторизация по клеймам возможна и достаточно проста в написании. Я написал подобное и уже года полтора в продакшне использую с большим успехом. Прототип можно поковырять здесь. Identity состоит на самом деле из нескольких пакетов: Microsoft.AspNet.Identity.Core - в основном интерфейсы и базовые имплементации классов которые не относятся к хранению данных Microsoft.AspNet.Identity.EntityFramework - имплементации классов которые относятся к хранению данных. Здесь все заточенно под EF, но все имплементации могут быть замененны на кастомное хранилище. Я видел пакеты которые позволяют хранить информацю о юзерах использую NHibernate или в RavenDb или Azure Tables. Так что хранилище может быть замененно без проблем. Microsoft.AspNet.Identity.Owin - адаптер для использования OWIN и создания кукисов через OWIN. В принципе тоже можно заменить, но не могу придумать зачем это менять. Claims - весьма удобная вещь. Все клеймы которые добавленны в запись юзера попадают в authentication куки и их оттуда можно достать без проблем. Их можно не использовать, но потратить полчаса на понимание как они работают и отказаться будет невозможно -). Когда создается печенка для входа на сайт, все пользователькие роли на самом деле записываются в куку как клеймы. Система потом достает из куки все клеймы с названием Role. То есть хочешь-не хочешь а клеймы используются по дефолту. Можно даже сказать что роли это по сути отдельный класс клеймов. Еще одна очень удобная вещь в Identity это SecurityStamp - GUID на записи пользователя. Если это поле меняется в базе, то сбрасываются все пользователькие куки и надо логиниться по-новой. Так можно легко предотвращать двух людей которые логинятся с разных компов под одним аккаунтом - полезно когда бизнес модель предполагает оплату по количеству аккаунтов.

понедельник, 23 декабря 2019 г.

Как в Razor-разметке получить дополнительные поля авторизованного пользователя?

#c_sharp #aspnet_core #razor #aspnet_identity_2 #aspnet_identity_3


@User.Identity.Name по сути выдает логин. А как получить тот же Age к примеру?

public class User : IdentityUser
{
    public int Age{ get; set; }
    public string FIO { get; set; }
    public string Addresses { get; set; }
}

    


Ответы

Ответ 1



По умолчанию используются только Name. Класс SignInManager регистрирует пользователей в вашем приложении. Этот класс использует IUserClaimsPrincipalFactory для регистрации claim'ов. Чтобы добавить claim нужно реализовать свой IUserClaimsPrincipalFactory public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory { public AppClaimsPrincipalFactory( UserManager userManager , RoleManager roleManager , IOptions optionsAccessor) : base(userManager, roleManager, optionsAccessor) { } public async override Task CreateAsync(ApplicationUser user) { var principal = await base.CreateAsync(user); if (user.Age > 0) { ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim("age", user.Age.ToString()) }); } return principal; } } Далее регистрируем в классе Startup в методе ConfigureServices после добавления Identity. public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddScoped, AppClaimsPrincipalFactory>(); ... } В представлении значение Age можно получить так: @User.Claims.Where(c => c.Type == "age").Select(c => c.Value).SingleOrDefault(); Для удобства можно создать метод расширения: public static class IdentityExtensions { public static string GetAge(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("age"); return (claim != null) ? claim.Value : string.Empty; } } И использовать в представлении так: @User.Identity.GetAge();

понедельник, 3 июня 2019 г.

Внедрение зависимостей в Owin

В базовом шаблоне при создании asp.net mvc проекта в качестве системы авторизации (по умолчанию) используется asp.net identity
public class ApplicationUser : IdentityUser { public async Task GenerateUserIdentityAsync( UserManager manager) {} }
public class ApplicationUserManager : UserManager { public ApplicationUserManager(IUserStore store) : base(store) {}
public static ApplicationUserManager Create( IdentityFactoryOptions options, IOwinContext context) {} }
public class ApplicationSignInManager : SignInManager { public ApplicationSignInManager( ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { }
public override Task CreateUserIdentityAsync(ApplicationUser user) {}
public static ApplicationSignInManager Create( IdentityFactoryOptions options, IOwinContext context) {} }
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) {}
static ApplicationDbContext() {}
public static ApplicationDbContext Create() {} }
Указанные выше классы используются при настройки авторизации в приложении
public partial class Startup { public void ConfigureAuth(IAppBuilder app) { // Configure the db context, user manager and role manager to use // a single instance per request app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext(ApplicationUserManager.Create); app.CreatePerOwinContext(ApplicationRoleManager.Create); app.CreatePerOwinContext(ApplicationSignInManager.Create);
} }
Как в приведенном коде избавиться от сильной зависимости - app.CreatePerOwinContext()?


Ответ

Воспользуемся IoC контейнером Autofac для внедрения зависимостей.
При помощи менеджера пакетов Nuget установим необходимые пакеты:
Autofac Autofac ASP.NET MVC 5 Integration Autofac OWIN Integration
Внесем следующие изменения в класс Startup
private void ConfigureContainer(IAppBuilder app) { var builder = new ContainerBuilder();
// STANDARD MVC SETUP:
// Register your MVC controllers. builder.RegisterControllers(typeof(MvcApplication).Assembly);
// Run other optional steps, like registering model binders, // web abstractions, etc., then set the dependency resolver // to be Autofac.
builder.RegisterType().As().InstancePerRequest(); builder.RegisterType() .As>().InstancePerRequest(); builder.RegisterType>() .As>().InstancePerRequest();
builder.Register((c, p) => c.Resolve() .Authentication).InstancePerRequest();
var dataProtectionProvider = app.GetDataProtectionProvider(); builder.Register>((c, p) => BuildUserManager(c, p, dataProtectionProvider));
var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// OWIN MVC SETUP:
// Register the Autofac middleware FIRST, then the Autofac MVC middleware. app.UseAutofacMiddleware(container); app.UseAutofacMvc(); }
private UserManager BuildUserManager( IComponentContext context, IEnumerable parameters, IDataProtectionProvider dataProtectionProvider) { var manager = new ApplicationUserManager(context.Resolve>()); // Configure validation logic for usernames manager.UserValidator = new UserValidator(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true };
// Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, };
// Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. // This application uses Phone and Emails as a step of receiving a code // for verifying the user // You can write your own provider and plug it in here. manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider { MessageFormat = "Your security code is {0}" }); manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider { Subject = "Security Code", BodyFormat = "Your security code is {0}" });
//manager.EmailService = new EmailService(); //manager.SmsService = new SmsService(); if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider( dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } }
Добавим вызов метода ConfigureContainer(IAppBuilder app) в метод Configuration(IAppBuilder app)
public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); ConfigureContainer(app); } }
После выше приведенных действий можно удалить методы app.CreatePerOwinContext() из метода ConfigureAuth()
так же необходимо модифицировать AccountControlle, ManageController
Убрать конструктор без параметров. Удалить следующие свойства: UserManager, SignInManager, AuthenticationManager
Вот так может выглядеть AccountController после внесения необходимых изменений:
public class AccountController : Controller { private readonly IAuthenticationManager _authenticationManager; private readonly SignInManager _signInManager; private readonly UserManager _userManager;
public AccountController( UserManager userManager, SignInManager signInManager, IAuthenticationManager authenticationManager) { _authenticationManager = authenticationManager; _userManager = userManager; _signInManager = signInManager; } //Прочие необходимые методы }
Использованные источники информации:
Autofac’s documentation Habrahabr

пятница, 15 февраля 2019 г.

Как узнать на сайте ли пользователь или нет?

То есть как в вк: проверяется на сайте ли пользователь, и потом пишет. И мне интересно как это делается. Знает ли кто эту страшную тайну?


Ответ

В случае VK, если говорить про почту, используется Long Polling, отправляются запросы на imxxx и al_im.php
Т.е, если неплохая достаточно точность нужна, то клиент должен пинговать сервак периодически.
Если точность особо не важна, то можно запоминать последнее время, когда человек заходил на сайт или когда посылал к серваку последний запрос. Это и будет, по сути, временем, когда человек последний раз был онлайн.

пятница, 14 декабря 2018 г.

ASP.NET Identity VS Самописная система авторизации

Может показаться что это очень "холиварный" вопрос, но я всё же задам его.
Начинал писать свою систему ещё тогда, когда был в моде ASP.NET Membership. Ну естественно, гибкости мне далеко не хватало и я решил писать свою систему авторизации, не опираясь на какие-то устоявшиеся в те времена принципы разработки авторизационных/аутентификационных систем. Что примерно из себя напоминает система сейчас:
Отдельный контекст (мало ли что в жизни бывает); CodeFirst - реализация; Хранение токена сессии в кукисах и сравнение его с токеном в отдельной таблице в БД. Авторизационные фильтры типа ([IdentityFilter("admin", "user", "manager")]) и типа ([IdentityFilter(RolesEnum.Manager)]). На выбор ;) Репозиторий. Авторизационная информация получается в фильтре и далее гуляет в HttpContext`e. Ну и много других мелочей.
Так вот, как бы работает быстро, но что то подсказывает мне, что можно ещё быстрее.
Собственно хотелось узнать, какие преимущества может нести для меня Identity и целесообразно ли его использование в "реальном продакшне", или же это интерфейс для новичков, и для тех, кто не хочет парится.
Ведь в моём коде для меня нет никаких ограничений, а вот в Identity ограничения всё таки есть, хотя бы то же самое именование таблиц и полей по умолчанию.
P.S. Прошу очень развёрнутый, и тем более аргументированный ответ. Заранее спасибо!


Ответ

Membership забыл как страшный сон, перешел на Identity
Нужна простая авторизация без лишней возни? - пожалуйста. Добавил подсистему и забыл. Нужно использовать Claims? - пожалуйста. Не нужно? - можно добавить в любой момент, а до тех пор хранить все основной таблице. А Claims так и будет ждать своего часа. Нужно добавить авторизацию через соцсети? - пожалуйста. Не нравятся именование полей или самой таблицы? - можно все переименовать. Нужно добавить новое поле? - пожалуйста. Автоматическая миграция, ничего не нужно удалять или бэкапить. Необходима двухфакторная аутентификация с подтверждением по смс или электронной почте? - Всё есть, просто добавить необходимые службы. Дополнительные требования к логинам и паролям? - орудия пыток на выбор:
AllowOnlyAlphanumericUserNames, RequireUniqueEmail // ------------------- RequiredLength = 6, RequireNonLetterOrDigit = false, RequireDigit = false, RequireLowercase = false, RequireUppercase = false
и т.д. и т.п.
Проще в студии загрузить готовый шаблон и поковырять его пару вечерков, чтобы точно убедиться подходит ли Identity для своих нужд. Для загрузки рабочего примера с комментариями в консоли пишем «Install-Package Microsoft.AspNet.Identity.Samples -Pre»
Update
Если нужно простое, гибкое, функциональное и готовое решение - Asp.net Identity подойдет. Все в коробке. Если необходимо реализовывать сложные сценарии: глубокие политики безопасности, одновременная аутентификация по Active Directory, сертификатам, токенам, онлайн формам (как на всех сайтах), то советую обратить внимание на Windows Identity Foundation. Придется несколько попотеть.

понедельник, 19 ноября 2018 г.

Как в Razor-разметке получить дополнительные поля авторизованного пользователя?

@User.Identity.Name по сути выдает логин. А как получить тот же Age к примеру?
public class User : IdentityUser { public int Age{ get; set; } public string FIO { get; set; } public string Addresses { get; set; } }


Ответ

По умолчанию используются только Name.
Класс SignInManager регистрирует пользователей в вашем приложении. Этот класс использует IUserClaimsPrincipalFactory для регистрации claim'ов. Чтобы добавить claim нужно реализовать свой IUserClaimsPrincipalFactory
public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory { public AppClaimsPrincipalFactory( UserManager userManager , RoleManager roleManager , IOptions optionsAccessor) : base(userManager, roleManager, optionsAccessor) { }
public async override Task CreateAsync(ApplicationUser user) { var principal = await base.CreateAsync(user);
if (user.Age > 0) { ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim("age", user.Age.ToString()) }); }
return principal; } }
Далее регистрируем в классе Startup в методе ConfigureServices после добавления Identity.
public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders();
services.AddScoped, AppClaimsPrincipalFactory>();
... }
В представлении значение Age можно получить так:
@User.Claims.Where(c => c.Type == "age").Select(c => c.Value).SingleOrDefault();
Для удобства можно создать метод расширения:
public static class IdentityExtensions { public static string GetAge(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("age"); return (claim != null) ? claim.Value : string.Empty; } }
И использовать в представлении так:
@User.Identity.GetAge();