Skip to content

Commit

Permalink
Merge pull request #11 from bugnabuggy/n2n/9
Browse files Browse the repository at this point in the history
n2n/9 Add JWT authorization for N2N.Api project and n2n/10 Add User r…
  • Loading branch information
LICH010 authored Dec 22, 2017
2 parents a521e82 + 9172cb4 commit ed04e84
Show file tree
Hide file tree
Showing 21 changed files with 593 additions and 82 deletions.
1 change: 1 addition & 0 deletions src/N2N.Api/Configuration/AppStart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ internal static void InitializeContainer(IApplicationBuilder app, Container cont
// Dependencies
container.Register<IRepository<N2NUser>, DbRepository<N2NUser>>();
container.Register<IRepository<N2NToken>, DbRepository<N2NToken>>();
container.Register<IRepository<N2NRefreshToken>, DbRepository<N2NRefreshToken>>();
container.Register<ISecurityService, SecurityService>();
container.Register<IN2NUserService, N2NUserService>();
container.Register<N2NApiUserService>();
Expand Down
14 changes: 14 additions & 0 deletions src/N2N.Api/Configuration/IConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace N2N.Api.Configuration
{
interface IConfig
{
string ISSUER { get; set; }
string AUDIENCE { get; set; }
int LIFETIME { get; set; }
}
}
24 changes: 24 additions & 0 deletions src/N2N.Api/Configuration/RefreshTokenConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IdentityServer4.Test;
using Microsoft.IdentityModel.Tokens;

namespace N2N.Api.Configuration
{
public class RefreshTokenConfig : IConfig
{
public string ISSUER { get; set; }
public string AUDIENCE { get; set; }
public int LIFETIME { get; set; }

public RefreshTokenConfig()
{
this.ISSUER = "MyAuthServer"; // издатель токена
this.AUDIENCE = "*";
this.LIFETIME = 30; // время жизни токена (30 дней рекомендуемое)
}
}
}
16 changes: 12 additions & 4 deletions src/N2N.Api/Configuration/TokenConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@

namespace N2N.Api.Configuration
{
public class TokenConfig
public class TokenConfig :IConfig
{
public const string ISSUER = "MyAuthServer"; // издатель токена
public const string AUDIENCE = "*"; // потребитель токена
public string ISSUER { get; set; }
public string AUDIENCE { get; set; }
public int LIFETIME { get; set; }

public TokenConfig()
{
this.ISSUER = "MyAuthServer"; // издатель токена
this.AUDIENCE = "*";
this.LIFETIME = LIFETIME = 60; // время жизни токена (180 минут рекомендуемое)
}
const string KEY = "mysupersecret_secretkey!123"; // ключ для шифрации
public const int LIFETIME = 60; // время жизни токена (180 минут рекомендуемое)

public static SymmetricSecurityKey GetSymmetricSecurityKey()
{
return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KEY));
Expand Down
49 changes: 39 additions & 10 deletions src/N2N.Api/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,43 @@ public UserController(N2NApiUserService apiUserService, IAuthentificationService
this._apiUserService = apiUserService;
}

[N2NAutorizationFilter]
[HttpGet("/user/СheckUser")]
//[N2NAutorizationFilter]
[HttpGet("/user")]
public async Task<JsonResult> СheckUser()
{
var authHeader = HttpContext.Request.Headers["Authorization"];
string welcome_message ="Welcome "+_authentificationService.GetNameUser(authHeader.ToString());
return Json(welcome_message);
if (authHeader!="Bearer")
{
string welcome_message = "Welcome " + _authentificationService.GetNameUser(authHeader.ToString());
return Json(welcome_message);
}
return Json("You not authentification");
}


[HttpPost("/user/logIn")]
public async Task<IActionResult> LogIn([FromBody] UserRegistrationFormDTO userRegistration)
{

if (!userRegistration.NickName.IsNullOrEmpty() &&
!userRegistration.Password.IsNullOrEmpty() &&
!userRegistration.Capcha.IsNullOrEmpty())
{
var response =
await _authentificationService.Authentification(userRegistration.NickName,
userRegistration.Password);

if (response.ToString() == new { }.ToString())
{
return BadRequest("Invalid username or password.");

}
return Ok(response);
}
else
{
return BadRequest("fill in all the fields");
}
}

[HttpPost("/user/register")]
Expand All @@ -59,15 +89,14 @@ public async Task<IActionResult> Register([FromBody] UserRegistrationFormDTO use
return BadRequest(result.Messages);
}

var identity = await this._authentificationService.GetIdentity(userRegistration.NickName, userRegistration.Password);
if (identity == null)
var response =await _authentificationService.Authentification(userRegistration.NickName, userRegistration.Password);

if (response.ToString() == new { }.ToString())
{
Response.StatusCode = 400;
await Response.WriteAsync("Invalid username or password.");
return BadRequest("Invalid username or password.");

}
var response = await this._authentificationService.GetTokenObject(identity, user.Id);


return Ok(response);
}
else
Expand Down
5 changes: 5 additions & 0 deletions src/N2N.Api/N2N.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.1" />
Expand All @@ -29,4 +30,8 @@
<ProjectReference Include="..\N2N.Utilities\N2N.Utilities.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.VisualBasic" />
</ItemGroup>

</Project>
102 changes: 79 additions & 23 deletions src/N2N.Api/Services/AuthentificationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using IdentityServer4.Test;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
Expand All @@ -18,11 +19,14 @@ public class AuthentificationService : IAuthentificationService
{
private UserManager<N2NIdentityUser> _userManager;
private IRepository<N2NToken> _tokenRepo;
private IRepository<N2NRefreshToken> _RefreshTokenRepo;


public AuthentificationService(UserManager<N2NIdentityUser> userManager, IRepository<N2NToken> tokenRepo)
public AuthentificationService(UserManager<N2NIdentityUser> userManager, IRepository<N2NToken> tokenRepo, IRepository<N2NRefreshToken> RefreshTokenRepo)
{
this._userManager = userManager;
this._tokenRepo = tokenRepo;
this._RefreshTokenRepo = RefreshTokenRepo;
}

public string GetNameUser(string tokenString)
Expand Down Expand Up @@ -81,7 +85,65 @@ public void DeleteToken(string tokenString)

}

public async Task<ClaimsIdentity> GetIdentity(string nickName, string password)
public async Task<object> Authentification(string nickName, string password)
{
object response= new { };
var access_token = await GetToken(nickName,password);
if (access_token !="")
{
var refresh_token = await GetRefreshToken(nickName, password);
response= new
{
access_token = access_token,
refresh_token = refresh_token
};
}
return response;
}

public async Task<string> GetToken(string nickName, string password)
{
var Token="";
var tokenConfig = new TokenConfig();
var lifeTime = TimeSpan.FromMinutes(tokenConfig.LIFETIME);
var user = await this._userManager.FindByNameAsync(nickName);
var tokenId = Guid.NewGuid();

var claimIdentity = await GetIdentity(nickName, password, tokenId);
if (claimIdentity != null)
{
_tokenRepo.Add(new N2NToken
{
Id = tokenId,
N2NUserId = user.N2NUserId,
TokenExpirationDate = DateTime.Now.AddMinutes(tokenConfig.LIFETIME)
});
Token = await GetTokenObject(claimIdentity, user.N2NUserId, tokenConfig.ISSUER,
tokenConfig.AUDIENCE,
lifeTime);
}
return Token;
}

public async Task<string> GetRefreshToken(string nickName, string password)
{
var tokenConfig = new RefreshTokenConfig();
var lifeTime = TimeSpan.FromDays(tokenConfig.LIFETIME);
var user = await this._userManager.FindByNameAsync(nickName);
var tokenId = Guid.NewGuid();
_RefreshTokenRepo.Add(new N2NRefreshToken()
{
Id = tokenId,
N2NUserId = user.N2NUserId,
RefreshTokenExpirationDate = DateTime.Now.AddDays(tokenConfig.LIFETIME)
});
var claimIdentity = await GetIdentity(nickName, password, tokenId);
var refreshToken =await GetTokenObject(claimIdentity, user.N2NUserId, tokenConfig.ISSUER, tokenConfig.AUDIENCE,
lifeTime);
return refreshToken;
}

public async Task<ClaimsIdentity> GetIdentity(string nickName, string password,Guid tokenId)
{
var access = await this._userManager.CheckPasswordAsync(this._userManager.Users.FirstOrDefault(x => x.UserName == nickName), password);
if (access)
Expand All @@ -90,13 +152,6 @@ public async Task<ClaimsIdentity> GetIdentity(string nickName, string password)
string roleforToken;
var user = await this._userManager.FindByNameAsync(nickName);
var role = await this._userManager.IsInRoleAsync(user, "Admin");
var tokenId = Guid.NewGuid();
_tokenRepo.Add(new N2NToken
{
Id = tokenId,
N2NUserId = user.N2NUserId,
TokenExpirationDate = DateTime.Now.AddMinutes(TokenConfig.LIFETIME)
});
if (role != true)
{
roleforToken = "User";
Expand All @@ -123,23 +178,24 @@ public async Task<ClaimsIdentity> GetIdentity(string nickName, string password)
return null;
}

public async Task<object> GetTokenObject(ClaimsIdentity identity,Guid userId)
public async Task<string> GetTokenObject(ClaimsIdentity identity,Guid userId, string issuer , string audience, TimeSpan lifetime)
{

string response="";

var now = DateTime.Now;
// создаем JWT-токен
var jwt = new JwtSecurityToken(
issuer: TokenConfig.ISSUER,
audience: TokenConfig.AUDIENCE,
notBefore: now,
claims: identity.Claims,
expires: now.Add(TimeSpan.FromMinutes(TokenConfig.LIFETIME)),
signingCredentials: new SigningCredentials(TokenConfig.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256));
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var jwt = new JwtSecurityToken(
issuer: issuer,
audience: audience,
notBefore: now,
claims: identity.Claims,
expires: now.Add(lifetime),
signingCredentials: new SigningCredentials(TokenConfig.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256));
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

response = encodedJwt;


var response = new
{
access_token = encodedJwt,
};
return response;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/N2N.Api/Services/IAuthentificationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public interface IAuthentificationService
OperationResult ValidateTokenString(string tokenString);

void DeleteToken(string tokenString);
Task<object> GetTokenObject(ClaimsIdentity identity, Guid userId);
Task<ClaimsIdentity> GetIdentity(string nickName, string password);
Task<object> Authentification(string nickName, string password);
string GetNameUser(string tokenString);
}
}
6 changes: 4 additions & 2 deletions src/N2N.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public Startup(IConfiguration configuration, IHostingEnvironment env)
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var tokenConfig = new TokenConfig();

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
Expand All @@ -51,12 +52,12 @@ public void ConfigureServices(IServiceCollection services)
// укзывает, будет ли валидироваться издатель при валидации токена
ValidateIssuer = true,
// строка, представляющая издателя
ValidIssuer = TokenConfig.ISSUER,
ValidIssuer = tokenConfig.ISSUER,

// будет ли валидироваться потребитель токена
ValidateAudience = true,
// установка потребителя токена
ValidAudience = TokenConfig.AUDIENCE,
ValidAudience = tokenConfig.AUDIENCE,
// будет ли валидироваться время существования
ValidateLifetime = true,

Expand All @@ -78,6 +79,7 @@ public void ConfigureServices(IServiceCollection services)
.AddEntityFrameworkStores<N2NDataContext>()
.AddDefaultTokenProviders();

services.AddTransient<IRepository<N2NRefreshToken>, DbRepository<N2NRefreshToken>>();
services.AddTransient<IRepository<N2NToken>, DbRepository<N2NToken>>();
services.AddTransient<IAuthentificationService, AuthentificationService>();

Expand Down
15 changes: 15 additions & 0 deletions src/N2N.Core/Entities/N2NRefreshToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace N2N.Core.Entities
{
public class N2NRefreshToken
{
public Guid Id { get; set; }
public Guid N2NUserId { get; set; }
public DateTime RefreshTokenExpirationDate { get; set; }
}
}
1 change: 1 addition & 0 deletions src/N2N.Core/Entities/N2NToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class N2NToken
public Guid Id { get; set; }
public Guid N2NUserId { get; set; }
public DateTime TokenExpirationDate { get; set; }
public Guid IdRefreshToken { get; set; }

}
}
1 change: 1 addition & 0 deletions src/N2N.Core/N2N.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Entities\N2NRefreshToken.cs" />
<Compile Include="Entities\N2NToken.cs" />
<Compile Include="Entities\Postcard.cs" />
<Compile Include="Entities\UserAddress.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/N2N.Infrastructure/DataContext/N2NDataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public N2NDataContext(DbContextOptions<N2NDataContext> options)

public DbSet<N2NUser> N2NUsers { get; set; }
public DbSet<N2NToken> N2NTokens { get; set; }
public DbSet<N2NRefreshToken> N2NRefreshTokens { get; set; }


protected override void OnModelCreating(ModelBuilder builder)
Expand Down
Loading

0 comments on commit ed04e84

Please sign in to comment.