Asp.net Core Object reference not set to an instance of an object - api

ASP.NET CORE API
The logged in user gives an error in the code below while adding a photo. Can anybody help?
var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value)
This code gives an error. Help me
Object reference not set to an instance of an object
PhotosController.cs
[HttpPost]
public ActionResult AddPhotoForCity(int cityId,[FromForm]PhotoForCreationDto photoForCreationDto)
{
var city = _appRepository.GetCityById(cityId);
if (city == null)
{
return BadRequest("Could not find the city.");
}
var currentUserId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
karşılaştırmak gibi
if (currentUserId != city.UserId)
{
return Unauthorized();
}
var file = photoForCreationDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var steam = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name,steam)
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
photoForCreationDto.Url = uploadResult.Url.ToString();
photoForCreationDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(photoForCreationDto);
photo.City = city;
if (!city.Photos.Any(p => p.IsMain))
{
photo.IsMain = true;
}
city.Photos.Add(photo);
if (_appRepository.SaveAll())
{
//eklenen fotoğrafı döndürüyoruz
var photoToRetun = _mapper.Map<Photo>(photoForCreationDto);
return CreatedAtRoute("GetPhoto", new {id = photo.Id}, photoToRetun);
}
return BadRequest("Cloud not add the photo");
}
AuthController.cs
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private IAuthRepository _authRepository;
private IConfiguration _configuration;
public AuthController(IAuthRepository authRepository, IConfiguration configuration)
{
_authRepository = authRepository;
_configuration = configuration;
}
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] UserForRegisterDto userForRegisterDto)
{
if (await _authRepository.UserExists(userForRegisterDto.UserName))
{
ModelState.AddModelError("UserName", "Username already exists");
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var userToCreate = new User
{
UserName = userForRegisterDto.UserName
};
var createdUser = await _authRepository.Register(userToCreate, userForRegisterDto.Password);
return StatusCode(201);
}
[HttpPost("login")]
public async Task<ActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
{
var user = await _authRepository.Login(userForLoginDto.UserName, userForLoginDto.Password);
if (user == null)
{
return Unauthorized();
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_configuration.GetSection("AppSettings:Token").Value);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName)
}),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key)
, SecurityAlgorithms.HmacSha512Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return Ok(tokenString);
}
}

From the above code snippet you have shared, they mostly likely reason you are getting this error is because the user is not logged in, and hence this line of code
User.FindFirst(ClaimTypes.NameIdentifier).Value
is throwing an exception.
You could either do it like this.
User.FindFirst(ClaimTypes.NameIdentifier)?.Value
Or
[HttpPost]
[Authorize] // make sure you authorize your action method by adding this attribute and
// only allow logged in user to access it.
public ActionResult AddPhotoForCity(int cityId,[FromForm]PhotoForCreationDto photoForCreationDto)
{
}

try this one:
var currentUserId = int.Parse(User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value);

Related

How to create a service for user login in Identity

In order to create a token in jwt, I must first check that the received user password is correct. I want to write a service for login and create its interface and use it in the JWTAuthorizationManager class or anywhere, please correct the codes.
public class JWTAuthorizationManager
{
public JwtFeilds Authenticate(string UserName, string PasswordHash)
{
//ایجاد تاریخ انقضای توکن
var tokenExpireTimeStamp = DateTime.Now.AddHours(Constansts.JWT_TOKEN_EXPIRE_TIME);
//ایجاد متغیر از کلاس مشخص شده برای ایجاد توکن و اطلاعات همراه آن
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
//ایجاد آرایه ای از بایت ها به عنوان کلید توکن
var tokenKey = Encoding.ASCII.GetBytes(Constansts.JWT_SECURITY_KEY_FOR_TOKEN);
//از این کلاس برای نگهداری ویژگیها و اطلاعات درون توکن استفاده می شود.
var securityTokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new List<Claim>
{
new Claim("username", UserName),
new Claim(ClaimTypes.PrimaryGroupSid,"User Group 01")
}),
Expires = tokenExpireTimeStamp,
//امضا یا اعتبارنامه یا مجوز ورود
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey),SecurityAlgorithms.HmacSha256Signature)
};
var securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
var token = jwtSecurityTokenHandler.WriteToken(securityToken);
return new JwtFeilds
{
token = token,
user_name = UserName,
expire_time = (int)tokenExpireTimeStamp.Subtract(DateTime.Now).TotalSeconds
};
}
}
public class loginService
{
private readonly SignInManager<User> _signInManager;
public loginService(SignInManager<User> signInManager)
{
_signInManager = signInManager;
}
public async Task<loginService> UserLogin(string UserName, string PasswordHash)
{
var result = await _signInManager.PasswordSignInAsync(UserName, PasswordHash, true,
lockoutOnFailure: false);
if (result.Succeeded)
{
return null;
}
return null;
}
}
interface IuserLogin
{
}
[HttpPost]
public IActionResult Login([FromForm] User model)
{
var jwtAuthorizationManager = new JWTAuthorizationManager();
var result = jwtAuthorizationManager.Authenticate(model.UserName, model.PasswordHash);
if (result == null)
return Unauthorized();
else
return Ok(result);
}
The token creation is done successfully, but I want the user to be identified before creating the token
The easiest way, you can choose to return a boolean Task:
public interface ILoginService
{
//If your model has other attributes, pass them in together
Task<bool> UserLogin(string UserName, string PasswordHash);
}
public class Login : ILogin
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
public Login(SignInManager<IdentityUser> signInManager,UserManager<IdentityUser> userManager)
{
_signInManager = signInManager;
_userManager = userManager;
}
public async Task<bool> UserLogin(string UserName, string PasswordHash)
{
var user = await _userManager.FindByEmailAsync(UserName);
if (user != null && !user.EmailConfirmed)
{
return false;
}
if (await _userManager.CheckPasswordAsync(user, PasswordHash) == false)
{
return false;
}
var result = await _signInManager.PasswordSignInAsync(UserName, PasswordHash, true);
if (result.Succeeded)
{
return true;
}
else
{
return false;
}
}
}
In the Login Action:
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(UserLoginDto model)
{
if (ModelState.IsValid)
{
//Call the ILoginService interface
var result = _loginService.UserLogin(model.Email,model.Password);
if (result.Result)
{
var jwtAuthorizationManager = new JWTAuthorizationManager();
var result = jwtAuthorizationManager.Authenticate(model.UserName, model.PasswordHash);
//do something
}
else
{
ModelState.AddModelError("message", "Invalid login attempt");
return View(model);
}
}
return View(model);
}
Don't forget to sign up for the service:
builder.Services.AddTransient<ILoginService, LoginService>();
You can also return a string or other types of Task, up to you.
Hope this can help you.

How to return a cookie from an ASP.NET Core Auth Cookie in a Controller

I currently have a razor page where I return a cookie and it works great. However, I am developing a SPA which uses VueJS so I have created an API to directly communicate with. I have converted my code from the Razor Page to the controller but I am not sure how I actually return the cookie when the user tries to log in. If there is a match I want it to return the cookie and create the cookie. As of now I get a 400 code as if this request is not working. Any thoughts what could be wrong with this?
public class LoginController : Controller
{
private readonly LoginDBContext _context;
private string connectionString;
public IConfiguration Configuration { get; }
public LoginController(LoginDBContext context, IConfiguration configuration)
{
_context = context;
connectionString = configuration["ConnectionStrings:MMCARMSContext"];
}
// GET: HomeController
public ActionResult Index()
{
return Ok(new { Result = "Test" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login([FromForm] string Username, [FromForm] string Password, [FromForm] bool RememberMe)
{
if (!String.IsNullOrEmpty(Username) && !String.IsNullOrEmpty(Password))
{
var users = _context.UsersAccountsTbl
.Where(a => a.Username == Username)
.Select(a => new { a.InternalUserNumber, a.Username, a.Password })
.ToArray();
if (users.Length == 1) //if we have more than 1 result we have security issue so do not allow login
{
var passwordHasher = new PasswordHasher<string>();
//To use you need to has with var hashedPassword = passwordHasher.HashPassword(UserName, Password);
//System.Diagnostics.Debug.WriteLine(passwordHasher.HashPassword("Username", "password"));
var user = users.First();
if (passwordHasher.VerifyHashedPassword(user.Username, user.Password, Password) == PasswordVerificationResult.Success)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.InternalUserNumber.ToString())
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
if (RememberMe)
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = RememberMe,
ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2)
});
}
else
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
}
return Ok(new { Result = "Cookie has been created!" });
}
else
{
return Ok(new { Result = "Password is incorrect!" });
}
}
return Ok(new { Result = "Username or Password does not exist!" });
}
else
{
return Ok(new { Result = "Username or Password invalid!" });
}
}
}
You could set the cookie in the HttpResponse, this way the cookie gets added when the client receives the response from your controller:
HttpCookie MyCookie = new HttpCookie("LastVisit");
DateTime now = DateTime.Now;
MyCookie.Value = now.ToString();
MyCookie.Expires = now.AddHours(1);
Response.Cookies.Add(MyCookie);
https://learn.microsoft.com/en-us/dotnet/api/system.web.httpresponse.cookies?view=netframework-4.8

Pass claims from WebApp to API

I am developing a web application and want to pass some custom claim to the API. I have the following code to set a user claim and call the API. I am expecting to access this claim in the API, but it's not happening. Can someone help, please? How do we pass the claim and other identity information from a web application to the API.
public async Task<IActionResult> Privacy3()
{
SetClaim("db2");
var httpClient = _clientFactory.CreateClient("NewApi");
var api = new HttpRequestMessage(HttpMethod.Get, "/api/customer");
var response = await httpClient.SendAsync(api);
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync();
var data = await JsonSerializer.DeserializeAsync<IEnumerable<Customer>>(responseStream, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
return View(data);
}
else
{
return View();
}
}
private ClaimsPrincipal SetClaim(string id)
{
if (id == null || id == "")
{
id = "db1";
}
ClaimsPrincipal principal = HttpContext.User;
var identity = (ClaimsIdentity)principal.Identity;
identity.AddClaim(new Claim("db", id));
return principal;
}
My API code is as below
public void ConfigureServices(IServiceCollection services)
{
//From Mr Browne
services.AddControllers();
services.AddHttpContextAccessor();
services.AddDbContext<CustomerDataContext>((sp, options) =>
{
var requestContext = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
var constr = GetConnectionStringFromRequestContext(requestContext);
options.UseSqlServer(constr, o => o.UseRelationalNulls());
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "AspNetCoreEfTest", Version = "v1" });
});
}
private string GetConnectionStringFromRequestContext(HttpContext requestContext)
{
var host = requestContext.User;
var dbname = "AspNetCoreEfTest";
if (host.Claims.Count(e => e.Type == "db") > 0)
{
var db = host.Claims.FirstOrDefault(e => e.Type == "db").Value;
if (db == "db1")
{
dbname = "AspNetCoreEfTest";
}
else if (db == "db2")
{
dbname = "AspNetCoreEfTestTwo";
}
}
return "Server=(localdb)\\mssqllocaldb;Database=" + dbname + ";Integrated Security=true";
}

How to extract methods from controller?

I want to extract "what I can" to the service. I have this method in the controller:
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
LoginViewModel loginViewModel = new LoginViewModel
{
ReturnUrl = returnUrl,
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
return View("Login", loginViewModel);
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ModelState.AddModelError(string.Empty, "Error loading external login information.");
return View("Login", loginViewModel);
}
var signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (signInResult.Succeeded)
{
return LocalRedirect(returnUrl);
}
else
{
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
if (email != null)
{
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
user = new ApplicationUser
{
UserName = info.Principal.FindFirstValue(ClaimTypes.Email),
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
};
await _userManager.CreateAsync(user);
}
await _userManager.AddLoginAsync(user, info);
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
ViewBag.ErrorTitle = $"Nie otrzymano informacji o adresie e-mail od dostawcy: {info.LoginProvider}";
ViewBag.ErrorMessage = "Proszę skontaktować się z supportem fryzjer#aplikacjafryzjer.com";
return View("Error");
}
}
Some properties are available only for classes that inherit from Controller, eg. ModelState or Url.
Can I extract these parts of the code too? A service can inherit from a controller, but won't it become a controller then?
------------------------------------------------------------ EDIT ---------------------------------------------------------------
Ok I tried separate my method from the controller. Below my previous code Controller:
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailService _emailService;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailService emailService)
{
_userManager = userManager;
_signInManager = signInManager;
_emailService = emailService;
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
//register functionality
var user = new ApplicationUser
{
FirstName = model.FirstName,
LastName = model.LastName,
UserName = model.Email,
Email = model.Email,
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
if (_signInManager.IsSignedIn(User) && User.IsInRole("Admin"))
{
return RedirectToAction("ListUsers", "Administrator");
}
//login user
await _signInManager.SignInAsync(user, isPersistent: false);
//generation of the email token
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var link = Url.Action(nameof(VerifyEmail), "Home", new { userId = user.Id, code }, Request.Scheme, Request.Host.ToString());
await _emailService.SendAsync(user.Email, "Weryfikacja adresu e-mail", $"Potwierdź e-mail", true);
return RedirectToAction("EmailVerification");
}
}
return View(model);
}
}
And my Controller now:
public class AccountController : Controller
{
private readonly IUserManager _userManager;
public AccountController(
IUserManager userManager)
{
_userManager = userManager;
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
(string action, string controller) = await _userManager.Register(model);
return RedirectToAction(action, controller);
}
return View(model);
}
}
I am sure, something is wrong. I have no idea how separate this logic from the controller, but on the other forums I heard "U have to separate your logic from the controller! Your controller have to be simple - only get request and send response, thats all!". but now, when I started rebuild my project, I am not sure isn't this more complicated...
In my service I return a tuple (???), because I have not better idea...
public async Task<(string, string)> Register(RegisterViewModel model)
{
//register functionality
var user = new ApplicationUser
{
FirstName = model.FirstName,
LastName = model.LastName,
UserName = model.Email,
Email = model.Email,
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
if (_signInManager.IsSignedIn(User) && User.IsInRole("Admin"))
{
return ("ListUsers", "Administrator");
}
//login user
await _signInManager.SignInAsync(user, isPersistent: false);
//generation of the email token
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var link = _urlHelper.Action(nameof(VerifyEmail), "Home", new { userId = user.Id, code });
await _emailService.SendAsync(user.Email, "Weryfikacja adresu e-mail", $"Potwierdź e-mail", true);
return ("EmailVerification", "Administrator");
}
return ("Register", "Administrator");
}
As far as I know, if you want to use Url in other custom service which is not inherit from controller. You could inject the IActionContextAccessor and use IUrlHelperFactory to create the it. Besides, if you want to use other controller based property or method, you could refer asp.net core source codes and find it work and then you could write the codes by yourself.
More details, you could refer to below codes:
Firstly you could inject the IActionContextAccessor in the startup.cs ConfigureServices method:
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
Then you could use DI and factory to create the URLhelper like below:
public class GetRoute : IGetRoute
{
private IUrlHelper _urlHelper;
private IActionContextAccessor _IActionContextAccessor;
public IUrlHelper Url
{
get
{
if (_urlHelper == null)
{
_urlHelper = _urlHelperFactory.GetUrlHelper(_IActionContextAccessor.ActionContext);
}
return _urlHelper;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_urlHelper = value;
}
}
private readonly IUrlHelperFactory _urlHelperFactory ;
public GetRoute(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider, IUrlHelperFactory urlHelperFactory, IActionContextAccessor actionContextAccessor)
{
_IActionContextAccessor = actionContextAccessor;
_urlHelperFactory = urlHelperFactory;
}
public string Getlink() {
return Url.Link("default", "aaaa");
}
}

Why [Authorize] attribute return 401 status code JWT + Asp.net Web Api?

I'm having big trouble finding issue with the JWT token authentication with asp.net web api. This is first time I am dealing with JWT & Web Api authentication & Authorization.
I have implemented the following code.
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new OAuthTokenProvider(),
RefreshTokenProvider = new RefreshTokenProvider(),
AccessTokenFormat = new Provider.JwtFormat("http://localhost:49860")
};
// OAuth 2.0 Bearer Access Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
private void ConfigureOAuthTokenConsumption(IAppBuilder app)
{
var issuer = "http://localhost:49860";
string audienceId = Config.AudienceId;
byte[] audienceSecret = TextEncodings.Base64Url.Decode(Config.AudienceSecret);
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audienceId },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
}
});
}
}
OAuthTokenProvider.cs
public class OAuthTokenProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// validate client credentials (demo)
// should be stored securely (salted, hashed, iterated)
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var allowedOrigin = "*";
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
/***Note: Add User validation business logic here**/
if (context.UserName != context.Password)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{ "as:client_id", "Kaushik Thanki" }
});
ClaimsIdentity oAuthIdentity = new ClaimsIdentity("JWT");
var ticket = new AuthenticationTicket(oAuthIdentity, props);
context.Validated(ticket);
}
}
JwtFormat.cs
public class JwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private readonly string _issuer = string.Empty;
public JwtFormat(string issuer)
{
_issuer = issuer;
}
public string Protect(AuthenticationTicket data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
string audienceId = Config.AudienceId;
string symmetricKeyAsBase64 = Config.AudienceSecret;
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime);
var handler = new JwtSecurityTokenHandler();
var jwt = handler.WriteToken(token);
return jwt;
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
RefreshTokenProvider.cs
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();
// maybe only create a handle the first time, then re-use for same client
// copy properties and set the desired lifetime of refresh token
var refreshTokenProperties = new AuthenticationProperties(context.Ticket.Properties.Dictionary)
{
IssuedUtc = context.Ticket.Properties.IssuedUtc,
ExpiresUtc = DateTime.UtcNow.AddYears(1)
};
var refreshTokenTicket = new AuthenticationTicket(context.Ticket.Identity, refreshTokenProperties);
//_refreshTokens.TryAdd(guid, context.Ticket);
_refreshTokens.TryAdd(guid, refreshTokenTicket);
// consider storing only the hash of the handle
context.SetToken(guid);
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;
if (_refreshTokens.TryRemove(context.Token, out ticket))
{
context.SetTicket(ticket);
}
}
}
Now Once I pass the authentication (Which I kept dummy for initial level matching same username & password) & got the token & refresh token.
When I request for method that is decorated with [Authorize] attribute, I always gets 401 status code.
I testing this method in postman following way
Any help or guidance will be really appreciated. I have invested my two days finding the solution for this but all in vain.