- 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"; } }
-
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 [email protected]? 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 [email protected]. 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 [email protected]. 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 [email protected] 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 check
var 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
-
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