Step 1: Create .net core auth project
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
</ItemGroup>
</Project>
Step 2: Add Microsoft.AspNetCore.Authentication.JwtBearer and mongodb package
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.5" />
<PackageReference Include="MongoDB.Driver" Version="2.10.4" />
</ItemGroup>
</Project>
Step 3: Create Model UserDetails
namespace FST.EasyCart.Auth.Model
{
public class UserDetails
{
public int UserId { get; set; }
public string UserName { get; set; }
public UserRole UserRole { get; set; }
public string Password { get; set; }
}
}
Step 4: Create Model Auth
namespace FST.EasyCart.Auth.Model
{
public enum UserRole
{
User,
Admin
}
}
Step 5: Create IMongoDbData interface
namespace FST.EasyCart.Auth.Data
{
public interface IMongoDbData
{
Task<UserDetails> GetUserDetails(string userName, string password);
Task SaveUserDetails(UserDetails userDetails);
}
}
Step 6: Create MongoDbData class
namespace FST.EasyCart.Auth.Data
{
public class MongoDbData : IMongoDbData
{
private readonly IMongoClient _mongoClient;
private readonly IMongoCollection<UserDetails> _userDetailsCol;
public MongoDbData(IMongoClient mongoClient)
{
BsonClassMap.RegisterClassMap<UserDetails>(c =>
{
c.AutoMap();
c.SetIgnoreExtraElements(true);
});
_mongoClient = mongoClient;
var mongoDb = _mongoClient.GetDatabase("Order");
_userDetailsCol = mongoDb.GetCollection<UserDetails>("UserDetails");
}
public async Task<UserDetails> GetUserDetails(string userName, string password)
{
var userDetails = await _userDetailsCol.FindAsync(f => f.UserName == userName && f.Password == password).ConfigureAwait(false);
while (await userDetails.MoveNextAsync()) {
if (userDetails.Current.Any()) {
return userDetails.Current.FirstOrDefault();
}
}
return null;
}
public Task SaveUserDetails(UserDetails userDetails)
{
return _userDetailsCol.InsertOneAsync(userDetails);
}
}
}
Step 7: Add Singleton service in Startup
public void ConfigureServices(IServiceCollection services)
{
var mongoCon = Configuration.GetSection("MongoDb")["MongoUrl"];
services.AddSingleton<IMongoClient>(new MongoClient(mongoCon));
services.AddSingleton<IMongoDbData, MongoDbData>();
services.AddControllers();
}
Step 8: Add mongo url in appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"MongoDb": {
"MongoUrl": "mongodb://localhost:27017"
}
}
Step 9: Create private and public certificate
openssl genrsa 2048 > private.key
openssl req -new -x509 -nodes -sha1 -days 1000 -key private.key > public.cer
openssl pkcs12 -export -in public.cer -inkey private.key -out cert_key.p12
Step 10: Create AuthController and add get,save and generate token method
namespace FST.EasyCart.Auth.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly ILogger<AuthController> _logger;
private readonly IMongoDbData _mongoDbData;
public AuthController(ILogger<AuthController> logger, IMongoDbData mongoDbData)
{
_logger = logger;
_mongoDbData = mongoDbData;
}
[HttpGet]
[Route("token")]
public async Task<IActionResult> Get()
{
var authBasicToken = HttpContext.Request.Headers["Authorization"].ToString();
if (!authBasicToken.StartsWith("Basic"))
{
return BadRequest();
}
var decodedAuthToken = Encoding.UTF8.GetString(Convert.FromBase64String(authBasicToken.Substring(6).Trim()));
var userNamePassword = decodedAuthToken.Split(":");
var userDetails = await _mongoDbData.GetUserDetails(userNamePassword[0], userNamePassword[1]).ConfigureAwait(false);
if(userDetails!=null)
//if (userNamePassword[0] == "admin" && userNamePassword[1] == "pass")
{
//var getClaimsData = repo.getdata(username);
var token = GenerateToken(userNamePassword[0]);
return Ok(token);
}
return BadRequest();
}
[HttpPost]
[Route("user")]
public async Task<IActionResult> Post(UserDetails userDetails)
{
try
{
await _mongoDbData.SaveUserDetails(userDetails).ConfigureAwait(false);
return Ok();
}
catch (Exception ex)
{
return BadRequest();
}
}
private string GenerateToken(string userName)
{
X509Certificate2 x509Certificate2 = new X509Certificate2(@"C:\Projects\Keys\cert_key.p12", "test");
//X509Certificate2 x509Certificate2 = GetCertificateFromStore();
X509SecurityKey x509SecurityKey = new X509SecurityKey(x509Certificate2);
var secToken = new JwtSecurityToken(
"www.errorandsolution.com",
"www.errorandsolution.com",
claims: new[] { new Claim(ClaimTypes.Name,userName) },
expires:DateTime.Now.AddMinutes(20),
signingCredentials:new SigningCredentials(x509SecurityKey,SecurityAlgorithms.RsaSha256Signature)
);
JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
return jwtSecurityTokenHandler.WriteToken(secToken);
}
private X509Certificate2 GetCertificateFromStore()
{
X509Store store = new X509Store(StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificate2Collection = store.Certificates;
X509Certificate2Collection currentCert = certificate2Collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection signCert = currentCert.Find(X509FindType.FindBySubjectDistinguishedName, "CN=www.errorandsolution.com, OU=Tech, O=FreeShareTechnology, L=Free, S=IT, C=US", false);
if (signCert.Count == 0) {
return null;
}
return signCert[0];
}
catch (Exception)
{
throw;
}
}
}
}
Video