2016-04-08 3 views
2

Есть ли способ сохранить некоторые пользовательские данные от пользователя внутри файла cookie, сгенерированного API-интерфейсом Identity?Сохранение пользовательских данных в Identity Cookie

Мы строим приложение с несколькими арендаторами, и поэтому несколько компаний могут получить доступ к тому же экземпляру нашего приложения. Вот почему мне нужен конкретный пользователь для хранения кода компании у пользователя в куки-файле идентификатора, чтобы получить данные от пользователя, когда он вернулся в веб-приложение после закрытия браузера.

ответ

12

вы могли бы достичь этого, внедрив пользовательский пользовательский интерфейс PrincipalFactory и добавив пользовательскую заявку на свой номер магазина, затем он будет храниться в файле cookie с другими претензиями.

Ниже приведен пример код из моего проекта, где я, добавив несколько пользовательских требований, включая SiteGuid, потому что мой сценарий также многопользовательский

using cloudscribe.Core.Models; 
using Microsoft.AspNet.Identity; 
using Microsoft.Extensions.OptionsModel; 
using System; 
using System.Security.Claims; 
using System.Threading; 
using System.Threading.Tasks; 

namespace cloudscribe.Core.Identity 
{ 
    public class SiteUserClaimsPrincipalFactory<TUser, TRole> : UserClaimsPrincipalFactory<TUser, TRole> 
    where TUser : SiteUser 
    where TRole : SiteRole 
{ 
    public SiteUserClaimsPrincipalFactory(
     ISiteRepository siteRepository, 
     SiteUserManager<TUser> userManager, 
     SiteRoleManager<TRole> roleManager, 
     IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor) 
    { 
     if (siteRepository == null) { throw new ArgumentNullException(nameof(siteRepository)); } 

     siteRepo = siteRepository; 
     options = optionsAccessor.Value; 
    } 

    private ISiteRepository siteRepo; 
    private IdentityOptions options; 

    public override async Task<ClaimsPrincipal> CreateAsync(TUser user) 
    { 
     if (user == null) 
     { 
      throw new ArgumentNullException("user"); 
     } 

     var userId = await UserManager.GetUserIdAsync(user); 
     var userName = await UserManager.GetUserNameAsync(user); 

     var id = new ClaimsIdentity(
      options.Cookies.ApplicationCookie.AuthenticationScheme, 
      Options.ClaimsIdentity.UserNameClaimType, 
      Options.ClaimsIdentity.RoleClaimType 
      ); 

      id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId)); 
      id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName)); 

      if (UserManager.SupportsUserSecurityStamp) 
      { 
       id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, 
       await UserManager.GetSecurityStampAsync(user))); 
      } 

      if (UserManager.SupportsUserRole) 
      { 
       var roles = await UserManager.GetRolesAsync(user); 
       foreach (var roleName in roles) 
       { 
        id.AddClaim(new Claim(Options.ClaimsIdentity.RoleClaimType, roleName)); 
        if (RoleManager.SupportsRoleClaims) 
        { 
         var role = await RoleManager.FindByNameAsync(roleName); 
         if (role != null) 
         { 
          id.AddClaims(await RoleManager.GetClaimsAsync(role)); 
         } 
        } 
       } 
      } 
      if (UserManager.SupportsUserClaim) 
      { 
       id.AddClaims(await UserManager.GetClaimsAsync(user)); 
      } 

      ClaimsPrincipal principal = new ClaimsPrincipal(id); 

      if (principal.Identity is ClaimsIdentity) 
      { 
       ClaimsIdentity identity = (ClaimsIdentity)principal.Identity; 

       Claim displayNameClaim = new Claim("DisplayName", user.DisplayName); 
       if (!identity.HasClaim(displayNameClaim.Type, displayNameClaim.Value)) 
       { 
        identity.AddClaim(displayNameClaim); 
       } 

       Claim emailClaim = new Claim(ClaimTypes.Email, user.Email); 
       if (!identity.HasClaim(emailClaim.Type, emailClaim.Value)) 
       { 
        identity.AddClaim(emailClaim); 
       } 

       ISiteSettings site = await siteRepo.Fetch(user.SiteId, CancellationToken.None); 

       if (site != null) 
       { 
        Claim siteGuidClaim = new Claim("SiteGuid", site.SiteGuid.ToString()); 
        if (!identity.HasClaim(siteGuidClaim.Type, siteGuidClaim.Value)) 
        { 
         identity.AddClaim(siteGuidClaim); 
        } 

       }  

      } 

      return principal; 

     } 
    } 
} 

Затем в запуске вам необходимо зарегистрировать свой собственный завод, так что получает инъекции и используется вместо значения по умолчанию один

services.AddScoped<IUserClaimsPrincipalFactory<SiteUser>, SiteUserClaimsPrincipalFactory<SiteUser, SiteRole>>(); 

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

public class ClaimsTransformer : IClaimsTransformer 
{ 
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) 
    { 
     ((ClaimsIdentity)principal.Identity).AddClaim(new Claim("ProjectReader", "true")); 
     return Task.FromResult(principal); 
    } 
} 

затем в startup.cs:

app.UseClaimsTransformation(new ClaimsTransformationOptions 
{ 
    Transformer = new ClaimsTransformer() 
}); 
+0

Благодаря это сработало! Я обошел все вещи о UserClaimsPrincipalFactory, потому что он слишком сложный для нашего использования, и я просто использую HttpContext, когда мне нужно его для входа. Я добавил еще две претензии и могу восстановить информацию о втором использовании моего приложения! :) –

+0

Джо, используя этот метод, может ли печенье быть подделано, например, злонамеренный пользователь, редактирующий «SiteGuid» своего файла cookie на что-то еще? Предоставленный действительный Guid будет трудно догадаться, но я рассматриваю возможность использования простых учетных записей (значений ключа в БД) для фильтрации доступа пользователей к данным. Это безопасно? –

+0

Я считаю, что Microsoft использует dataprotection api для шифрования ролей и претензий, хранящихся в файле cookie auth –

Смежные вопросы