-
What is your product version?
-
Product Version is 10.0.0
-
What is your product type (Angular or MVC)?
-
Angular
-
What is product framework type (.net framework or .net core)?
-
.net core
-
What is ABP Framework version?
-
6.1
I need some data to store in session which is reuse after logined.
I had override CreateAsync(User user) method in UserClaimsPrincipalFactory.cs. Look it
public override async Task CreateAsync(User user)
{
var claim = await base.CreateAsync(user);
var resObj = (from res in _reservationRepository.GetAll()
join gs in _guestRepository.GetAll() on res.GuestKey equals gs.Id
join r in _roomRepository.GetAll() on res.RoomKey equals r.Id
where (res.Status == 1 || res.Status == 2) && (gs.EMail == user.EmailAddress || gs.LastName == user.UserName)
select new
{
DocNo = res.DocNo,
ReservationKey = res.Id,
GuestKey = gs.Id
}).FirstOrDefault();
if (resObj != null)
{
claim.Identities.First().AddClaim(new Claim("Application_DOCNO", resObj.DocNo));
}
return claim;// it is ok. Docno value have in claims.
}
Then I created MyAppSession Class folowing :
public class MyAppSession : ClaimsAbpSession, ITransientDependency,IMyAppSession
{
public MyAppSession(
IPrincipalAccessor principalAccessor,
IMultiTenancyConfig multiTenancy,
ITenantResolver tenantResolver,
IAmbientScopeProvider<SessionOverride> sessionOverrideScopeProvider) :
base(principalAccessor, multiTenancy, tenantResolver, sessionOverrideScopeProvider)
{
}
public string DOCNO
{
get
{
var userDocClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "Application_DOCNO");
if (userDocClaim == null || string.IsNullOrEmpty(userDocClaim?.Value))
{
return null;
}
return userDocClaim.Value;
}
}
This is IMyAppSession Interface
public interface IMyAppSession
{
string DOCNO { get; }
}
This is session value retrive class
public class TokenAuthController : BEZNgCoreControllerBase
{
private readonly IMyAppSession \_p;
public TokenAuthController(IMyAppSession p)
{
\_p = p;
}
public string GetSession()
{
return _p.DOCNO;// Here value is null. Why?
}
}
Is there anything need to change? Please help me.
18 Answer(s)
-
0
Hi billyteng,
You need to replace the default UserClaimsPrincipalFactory in the IoC container.
Module code:public class YourApplicationModule : AbpModule { public override void PreInitialize() { IocManager.IocContainer.Register( Component .For<IUserClaimsPrincipalFactory<User>, CustomClaimFactory>() .LifestyleTransient() .IsDefault()); } }
Custom session code:
public class CustomClaimFactory : AbpUserClaimsPrincipalFactory<User, Role> { public CustomClaimFactory(AbpUserManager<Role, User> userManager, AbpRoleManager<Role, User> roleManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor) { } public override async Task<ClaimsPrincipal> CreateAsync(User user) { var claim = await base.CreateAsync(user); claim.Identities.First() .AddClaim(new Claim("Custom", "Hello World")); return claim; } } public interface ICustomAppSession { string Custom { get; } } public class CustomAppSession : ClaimsAbpSession, ITransientDependency, ICustomAppSession { public CustomAppSession(IPrincipalAccessor principalAccessor, IMultiTenancyConfig multiTenancy, ITenantResolver tenantResolver, IAmbientScopeProvider<SessionOverride> sessionOverrideScopeProvider) : base(principalAccessor, multiTenancy, tenantResolver, sessionOverrideScopeProvider) { } public string Custom { get { var userDocClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "Custom"); if (userDocClaim == null || string.IsNullOrEmpty(userDocClaim?.Value)) { return null; } return userDocClaim.Value; } } } public class TestAppService : QADemoDemoAppServiceBase { private readonly IUserClaimsPrincipalFactory<User> _claimsPrincipalFactory; private readonly ICustomAppSession _customAppSession; private readonly UserManager _userManager; public TestAppService(ICustomAppSession customAppSession, IUserClaimsPrincipalFactory<User> claimsPrincipalFactory, UserManager userManager) { _customAppSession = customAppSession; _claimsPrincipalFactory = claimsPrincipalFactory; _userManager = userManager; } public async Task<string> GetInfoAsync() { var user = await _userManager.GetUserByIdAsync(AbpSession.UserId.Value); var value = _customAppSession.Custom; var claims = await _claimsPrincipalFactory.CreateAsync(user); await Task.CompletedTask; return "Ok"; } }
Result:
-
0
Hi Zony,
Thanks for your reply. I did your follow. But it's still null value. Not show "Hello World". Look my code.In Application layer
public class NameNgCoreApplicationModule : AbpModule
{
public override void PreInitialize()
{
//Adding authorization providers
Configuration.Authorization.Providers.Add<AppAuthorizationProvider>();//Adding custom AutoMapper configuration Configuration.Modules.AbpAutoMapper().Configurators.Add(CustomDtoMapper.CreateMappings); //For CustomClaimFactory IocManager.IocContainer.Register( Component .For<IUserClaimsPrincipalFactory<User>, CustomClaimFactory>() .LifestyleTransient() .IsDefault()); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(BEZNgCoreApplicationModule).GetAssembly()); } }
I created "CustomClaimFactory" class in NameNgCore.Core project.
public class CustomClaimFactory : AbpUserClaimsPrincipalFactory<User, Role>
{
private readonly IRepository<Guest, Guid> _guestRepository;
private readonly IRepository<Reservation, Guid> _reservationRepository;
private readonly IRepository<Room, Guid> _roomRepository;public CustomClaimFactory(AbpUserManager<Role, User> userManager, AbpRoleManager<Role, User> roleManager, IOptions<IdentityOptions> optionsAccessor, IRepository<Guest, Guid> guestRepository, IRepository<Reservation, Guid> reservationRepository, IRepository<Room, Guid> roomRepository ) : base(userManager, roleManager, optionsAccessor) { _guestRepository = guestRepository; _reservationRepository = reservationRepository; _roomRepository = roomRepository; } public override async Task<ClaimsPrincipal> CreateAsync(User user) { var claim = await base.CreateAsync(user); var resObj = (from res in _reservationRepository.GetAll() join gs in _guestRepository.GetAll() on res.GuestKey equals gs.Id join r in _roomRepository.GetAll() on res.RoomKey equals r.Id where (res.Status == 1 || res.Status == 2) && (gs.EMail == user.EmailAddress || gs.LastName == user.UserName) select new { DocNo = res.DocNo, ReservationKey = res.Id, GuestKey = gs.Id }).FirstOrDefault(); // resObj has value if (resObj != null) { claim.Identities.First().AddClaim(new Claim("Application_DOCNO", "Hello World")); } return claim; } } public interface IMyAppSession { string DOCNO { get; } }
public class MyAppSession : ClaimsAbpSession, ITransientDependency,IMyAppSession
{
public MyAppSession(
IPrincipalAccessor principalAccessor,
IMultiTenancyConfig multiTenancy,
ITenantResolver tenantResolver,
IAmbientScopeProvider<SessionOverride> sessionOverrideScopeProvider) :
base(principalAccessor, multiTenancy, tenantResolver, sessionOverrideScopeProvider)
{
}
public string DOCNO
{
get
{
var userDocClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "Application_DOCNO");
if (userDocClaim == null || string.IsNullOrEmpty(userDocClaim?.Value))
{
return null;
}return userDocClaim.Value; } } } This is TokenAuthController in NameNgCore.Web.Core project which call store values public class TokenAuthController : NameNgCoreControllerBase { private readonly IUserClaimsPrincipalFactory<User> _iclaimsPrincipalFactory; private readonly IMyAppSession _p; public TokenAuthController(IMyAppSession p, IUserClaimsPrincipalFactory<User> iclaimsPrincipalFactory ) { _p = p; _iclaimsPrincipalFactory = iclaimsPrincipalFactory; } [HttpPost] public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model) { your code ...ok....then....... var loginResult = await GetLoginResultAsync( model.UserNameOrEmailAddress, model.Password, GetTenancyNameOrNull() ); .......... var refreshToken = CreateRefreshToken(await CreateJwtClaims(loginResult.Identity, loginResult.User, tokenType: TokenType.RefreshToken)); var accessToken = CreateAccessToken(await CreateJwtClaims(loginResult.Identity, loginResult.User, refreshTokenKey: refreshToken.key)); var claims = await _iclaimsPrincipalFactory.CreateAsync(loginResult.User); var d =_p.DOCNO ; // here value is null. Actually it must show "Hello World" return new AuthenticateResultModel { AccessToken = accessToken, ExpireInSeconds = (int)_configuration.AccessTokenExpiration.TotalSeconds, RefreshToken = refreshToken.token, RefreshTokenExpireInSeconds = (int)_configuration.RefreshTokenExpiration.TotalSeconds, EncryptedAccessToken = GetEncryptedAccessToken(accessToken), TwoFactorRememberClientToken = twoFactorRememberClientToken, UserId = loginResult.User.Id, ReturnUrl = returnUrl }; } } please help me..Is there anything path?
-
0
Hi billyteng,
It seems that there is no problem. Can you send the sample project to info@aspnetzero.com? Please include Question-9982 in the email. -
0
It seems that the value of resObj may be Null. I suggest you check whether this code is the expected situation.
if (resObj != null) { claim.Identities.First().AddClaim(new Claim("Application_DOCNO", "Hello World")); }
-
0
I have alread sent the files to your info@aspnetzero.com. Please check it.
-
0
Thanks, I will check it.
-
0
Hi Zony,
I can't hear anything from you. Please....
-
0
Hi @billyteng
Could you share your full project and steps to reproduce this problem to info@aspnetzero.com.
I will take care of it immediately.Thanks,
-
0
-
0
Hi @billyteng
Thanks, I have requested access, could you allow me to download the project ?
Thanks,
-
0
Hi @ismcagdas
Thanks reply. I have already shared with info@aspnetzero.com in google drive. Please look at it.
Thanks -
0
HI @ismcagdas
I have already change access permission. Now you can download it. Please....
Thanks
-
0
Hi ismcagdas,
Any update for above problems ?
Thanks
-
0
Hi ismcagdas,
Could you please take a look this case?
Thanks
-
0
Hi @billyteng
You are trying to get session value before it is initialized. Session value is null when use try to login, you can checkvar abpUser = AbpSession.ToUserIdentifier();
It will also be null.
Try to get it where session is set. For example in the logout of the same controller
.
And implementing custom session is very simple. No need to make it complex. Check that: https://aspnetboilerplate.com/Pages/Documents/Articles\How-To\add-custom-session-field-aspnet-core
Here are my changes for your implementation.
-
0
hi musa.demir ,
I will try and get back to you.
Thanks -
0
Hi @billyteng
Can we close this issue ?
Thanks,
-
0
Hi ismcagdas ,
Yes. we can close now .
Thanks