Cannot convert from System.security.claims.claimsPrincipal to Scheduler.Areas.Identity.Data - asp.net-core

I'm trying to get the current user ID so my Events index page will show events from only current user.
my HttpContext.User has the error "Cannot convert from System.security.claims.claimsPrincipal to Scheduler.Areas.Identity.Data" inside the index of my Events controller.
var userId = await _userManager.GetUserIdAsync(HttpContext.User);
Here is the code in my EventsController:
public EventsController(SchedulerDbContext context, UserManager<SchedulerUser> userManager)
{
_context = context;
_userManager = userManager;
}
// GET: Events
[Authorize]
public async Task<IActionResult> Index()
{
var userId = await _userManager.GetUserIdAsync(HttpContext.User);
return View(await _context.Events.Where(g => g.SchedulerUser == userId).ToListAsync());
}
Where should I be looking to solve this? I'll update with more code if required.

GetUserIdAsync only accepts an IdentityUser type. It doesn't accept a type of ClaimsPrincipal, but GetUserAsync does.
var user = await _userManager.GetUserAsync(HttpContext.User);
var userId = user.Id;
Alternatively, you could also get the Id claim from claimsidentity.
var userId = claimsIdentity.FindFirst("id")?.Value;

Related

how to get Username by id in identity?

I'm trying to get the user name by id and pass it to view by viewbag.
I can access the user by id but I can't access the user name.
I'm using identity 3 in asp.net core.
This is my action:
public IActionResult Index(string id)
{
var userCourse = _courseService.GetUserCourse(id);
var user = _userManager.FindByIdAsync(id);
return View(userCourse);
}
public async Task<IActionResult> Index(string id)
{
var userCourse = _courseService.GetUserCourse(id);
var user = await _userManager.FindByIdAsync(id);
ViewBag.UserName= user.UserName;
return View(userCourse);
}
And in View use viewbag.UserName to render userName
<label>User Name:</label> #ViewBag.UserName

Blazor server scoped service is different

I need to store the authenticated user Session Id, where access token is retrieved from dictionary per user session.
I have simple Scoped service services.AddScoped<SessionService>();
public class SessionService
{
public string SessionId { get; set; }
}
In MainLayout.razor I'm injecting it and setting it when the user log in. Which works fine.
#inject SessionService SessionService
.....
#code {
[CascadingParameter]
private Task<AuthenticationState> AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync()
{
SessionService.SessionId = (await AuthenticationStateTask).User.GetSessionId();
}
}
However, I'm creating HttpClient from IHttpClientFactory and getting the access token based on the user Session Id, but all 3 different approaches to get the SessionService have SessionId set to null
services.AddHttpClient("backend", async (provider, client) =>
{
var httpContextAccessor = provider.GetService<IHttpContextAccessor>();
var httpContextService = httpContextAccessor.HttpContext.RequestServices.GetService<SessionService>();
using var scope = provider.CreateScope();
var anotherProvider = services.BuildServiceProvider();
var anotherSession = anotherProvider.GetService<SessionService>();
var sessionId = scope.ServiceProvider.GetService<SessionService>()?.SessionId;
client.BaseAddress = ...;
});
If I use the service inside component the SessionId is what it has to be and not null. Why is that happening and how to fix it?

Get database record based on id

Greeting,
I have an website that display products everything okay until now but i want the current user that have logged in to get his/ her data only, eg. if the user has id=1 its will get all products will id=1 (i have foreign key constrain between the two tables) i am using very simple controller that only get all products, i didn't find any solution at google.
i am using .NET CORE 3.0 with EntityFramework and SQL SERVER database
i am currently using JWT token that is stored inside local storage at web browser.
here is my ProductsController
public class ProductsController : ControllerBase
{
private readonly IAuthRepository _repo;
private readonly DataContext _context;
public ProductsController(DataContext context, IAuthRepository repo)
{
_context = context;
_repo = repo;
}
[HttpGet]
public async Task<IActionResult> AllProducts()
{
var All = await _context.Product.ToListAsync();
return Ok(All);
}
below is the code to get userid from jwt token
var context = new HttpContextAccessor();
var principal = context.HttpContext.User;
if (null == principal)
return null;
var id = principal.FindFirstValue(ClaimTypes.NameIdentifier);
Then update your action method " AllProducts" to
[HttpGet]
public async Task<IActionResult> AllProducts()
{
var context = new HttpContextAccessor();
var principal = context.HttpContext.User;
if (null == principal)
return null;
var userid = principal.FindFirstValue(ClaimTypes.NameIdentifier);
var All = await _context.Product.where(p=>p.id==userid).ToListAsync();
return Ok(All);
}

How to retrieve parameters passed to AAD with Open ID Connect within the redirect Controller?

I am using Open Id Connect with Azure Active Directory for authentication. I am also setting a parameter to the OpenIdConnectChallengeProperties, so that I can retrieve this parameter in the controller action which is the redirect URL.
I did not find any information on how to do this.
My code is as follows.
AuthController.cs
[Route("auth/signin")]
[HttpPost]
public ActionResult SignIn([FromBody] RequestParams requestParams)
{
Guid guid = new Guid();
_cache.Set(guid, requestParams);
var baseURL = Request.Host;
var redirectURL = "https://" + baseURL + "/auth/redirect";
var properties = new OpenIdConnectChallengeProperties();
properties.SetParameter("id",guid);
properties.RedirectUri = redirectURL;
return Challenge(properties, AzureADDefaults.OpenIdScheme);
}
[Route("auth/redirect")]
[HttpGet]
public async Task<string> HandleAADRedirect()
{
if (User.Identity.IsAuthenticated)
{
string accessToken = await HttpContext.GetTokenAsync("access_token");
string idToken = await HttpContext.GetTokenAsync("id_token");
}
return _cache.Get("").ToString();
}
Once the user authenticates and goes back to your server, you can then access the property.
var result = await HttpContext.AuthenticateAsync(OpenIdConnectDefaults.AuthenticationScheme);
var value = result.Properties.Items["id"];

How to get ApplicationUser object for a given user

In my following action method I'm getting following design time error on line var result = await _userManager.AddToRoleAsync(user, "AdminRole");. But if I use var user = new ApplicationUser { UserName = model.SelectedUserName to get a user then the above line does not give design time error, however; as expected, it gives run time validation error as: User someUSerName already exist. I understand the run time error is due to the fact that I'm adding a role to an existing user but passing a new instance of it. Question: How can I get an existing user as an ApplicationUser object so I can pass it to AddToRoleAsync(....) below? I'm using ASP.NET Core 1.1.1, Individual User Accounts mode, VS2017.
Error:
Cannot convert from Task<MyProj.Model.ApplicationUser> to MyProj.Model.ApplicationUser
Controller
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddUserToRole(RoleRelatedViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = _userManager.FindByNameAsync(model.SelectedUserName); //cannot be used in AddToRoleAsync(user,"AdminRole") since FindByNameAsync returns Task<ApplicationUser>
//var user = new ApplicationUser { UserName = model.SelectedUserName };
var result = await _userManager.AddToRoleAsync(user, "AdminRole");
if (result.Succeeded)
{
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
try var user = await _userManager.FindByNameAsync(model.SelectedUserName);
it seems like AddToRoleAsync expects ApplicationUser as first parameter, but you giving Task
So if you use await before FindByNameAsync call your user variable will be ApplicationUser.