diff --git a/IdentityServer.Application/Services/UserService.cs b/IdentityServer.Application/Services/UserService.cs index fd6ce72..d96e064 100644 --- a/IdentityServer.Application/Services/UserService.cs +++ b/IdentityServer.Application/Services/UserService.cs @@ -21,7 +21,7 @@ namespace IdentityServer.Application.Services public async Task Authenticate(string userName, string password) { - var user = await _identityRepository.GetAppUser(userName, password); + var user = await _identityRepository.GetUser(userName, password); if (user == null) return null; @@ -29,6 +29,7 @@ namespace IdentityServer.Application.Services var currentDate = DateTime.Now; var token = new Token() { Raw = tokenRaw, ValidFrom = currentDate, ValidUntil = currentDate.AddMonths(12) }; _securityStore.SetToken(token, user.UserId); + await _identityRepository.UpdateUserAfterAuthentication(user, token); return token; } diff --git a/IdentityServer.Domain.Data/DbContexts/IdentityDbContext.cs b/IdentityServer.Domain.Data/DbContexts/IdentityDbContext.cs index 0f59e0b..9b50c20 100644 --- a/IdentityServer.Domain.Data/DbContexts/IdentityDbContext.cs +++ b/IdentityServer.Domain.Data/DbContexts/IdentityDbContext.cs @@ -7,6 +7,7 @@ namespace IdentityServer.Domain.Data.DbContexts public class IdentityDbContext : DbContext { public DbSet Users { get; set; } + public DbSet UserTokens { get; set; } public IdentityDbContext(DbContextOptions options) : base(options) @@ -22,6 +23,7 @@ namespace IdentityServer.Domain.Data.DbContexts modelBuilder.ApplyConfiguration(new UserStatusConfiguration()); modelBuilder.ApplyConfiguration(new AppUserConfiguration()); modelBuilder.ApplyConfiguration(new UserClaimConfiguration()); + modelBuilder.ApplyConfiguration(new UserTokenConfiguration()); } } } diff --git a/IdentityServer.Domain.Data/EntityTypeConfiguration/UserTokenConfiguration.cs b/IdentityServer.Domain.Data/EntityTypeConfiguration/UserTokenConfiguration.cs new file mode 100644 index 0000000..9343328 --- /dev/null +++ b/IdentityServer.Domain.Data/EntityTypeConfiguration/UserTokenConfiguration.cs @@ -0,0 +1,15 @@ +using IdentityServer.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace IdentityServer.Domain.Data.EntityTypeConfiguration +{ + class UserTokenConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("UserToken").HasKey(z => z.Id); + builder.Property(z => z.Id).ValueGeneratedOnAdd(); + } + } +} diff --git a/IdentityServer.Domain.Data/Repositories/IdentityRepository.cs b/IdentityServer.Domain.Data/Repositories/IdentityRepository.cs index 38545eb..0ce543d 100644 --- a/IdentityServer.Domain.Data/Repositories/IdentityRepository.cs +++ b/IdentityServer.Domain.Data/Repositories/IdentityRepository.cs @@ -1,7 +1,9 @@ using IdentityServer.Domain.Data.DbContexts; using IdentityServer.Domain.Entities; +using IdentityServer.Domain.Models; using IdentityServer.Domain.Repositories; using Microsoft.EntityFrameworkCore; +using System; using System.Threading.Tasks; namespace IdentityServer.Domain.Data.Repositories @@ -15,12 +17,29 @@ namespace IdentityServer.Domain.Data.Repositories _dbContext = dbContext; } - public Task GetAppUser(string userName, string password) + public Task GetUser(string userName, string password) { return _dbContext.Users .Include(z => z.Status) .Include(z => z.Claims) .FirstOrDefaultAsync(z => z.UserName == userName && z.Password == password); } + + public async Task UpdateUserAfterAuthentication(AppUser user, Token token) + { + var userToken = new UserToken() + { + UserId = user.UserId, + Token = token.Raw, + ValidFrom = token.ValidFrom, + ValidUntil = token.ValidUntil + }; + await _dbContext.AddAsync(userToken); + + user.LastLoginDate = DateTime.Now; + _dbContext.Update(user); + + await _dbContext.SaveChangesAsync(); + } } } diff --git a/IdentityServer.Domain.Data/Scripts/1.0.1/02.New structure for AppUser table.sql b/IdentityServer.Domain.Data/Scripts/1.0.1/02.New structure for AppUser table.sql index 911edc4..02b5df5 100644 --- a/IdentityServer.Domain.Data/Scripts/1.0.1/02.New structure for AppUser table.sql +++ b/IdentityServer.Domain.Data/Scripts/1.0.1/02.New structure for AppUser table.sql @@ -16,9 +16,9 @@ begin LastName varchar(100), Email varchar(100), ProfilePictureUrl varchar(200), - SecurityStamp varchar(200) constraint UQ_AppUser_SecurityStamp unique, + SecurityStamp varchar(200) not null constraint UQ_AppUser_SecurityStamp unique, StatusId int not null constraint FK_AppUser_UserStatus references UserStatus(StatusId), - CreationDate datetime constraint DF_AppUser_CreationDate default getdate(), + CreationDate datetime not null constraint DF_AppUser_CreationDate default getdate(), FailedLoginAttempts int, LastLoginDate datetime, PasswordChangeDate datetime diff --git a/IdentityServer.Domain.Data/Scripts/1.0.1/04.UserToken table.sql b/IdentityServer.Domain.Data/Scripts/1.0.1/04.UserToken table.sql new file mode 100644 index 0000000..baa31d7 --- /dev/null +++ b/IdentityServer.Domain.Data/Scripts/1.0.1/04.UserToken table.sql @@ -0,0 +1,12 @@ +if not exists (select top 1 1 from sys.objects where name = 'UserToken' and type = 'U') +begin + create table UserToken + ( + Id int identity(1, 1) constraint PK_Token primary key, + UserId int not null constraint FK_Token_AppUser foreign key references AppUser(UserId), + Token varchar(1000) not null, + ValidFrom datetime not null, + ValidUntil datetime not null + ) +end +go \ No newline at end of file diff --git a/IdentityServer.Domain/Entities/UserToken.cs b/IdentityServer.Domain/Entities/UserToken.cs new file mode 100644 index 0000000..5576ca6 --- /dev/null +++ b/IdentityServer.Domain/Entities/UserToken.cs @@ -0,0 +1,13 @@ +using System; + +namespace IdentityServer.Domain.Entities +{ + public class UserToken + { + public int Id { get; set; } + public int UserId { get; set; } + public string Token { get; set; } + public DateTime ValidFrom { get; set; } + public DateTime ValidUntil { get; set; } + } +} diff --git a/IdentityServer.Domain/Repositories/IIdentityRepository.cs b/IdentityServer.Domain/Repositories/IIdentityRepository.cs index 98479c2..3278867 100644 --- a/IdentityServer.Domain/Repositories/IIdentityRepository.cs +++ b/IdentityServer.Domain/Repositories/IIdentityRepository.cs @@ -1,10 +1,12 @@ using IdentityServer.Domain.Entities; +using IdentityServer.Domain.Models; using System.Threading.Tasks; namespace IdentityServer.Domain.Repositories { public interface IIdentityRepository { - Task GetAppUser(string userName, string password); + Task GetUser(string userName, string password); + Task UpdateUserAfterAuthentication(AppUser user, Token token); } }