admin管理员组文章数量:1335895
When using PasswordSignInAsync
from a SignInManager
, the result is a SignInResult
which tells me if the sign in succeeded or failed but doesn't actually containt the details like the access token. The token and other info is stored in AccessTokenResponse
, which appears to just be stored in the context. My question is, how can I intercept the AccessTokenResponse
in order to map it to a custom class? Other than that, this implementation is working well.
When calling PasswordSignInAsync
from an API method, it seems like the AccessTokenResponse
is already embedded in the response without me doing anything, so I'm unsure how I would access it.
Controller Method (using Mediatr)
[HttpPost("Login")]
[AllowAnonymous]
public async Task<Results<Ok<AccessTokenResponse>, EmptyHttpResult, ProblemHttpResult>> Login(LoginUserCommand command)
{
var response = await Mediator.Send(command);
if (!response.Success)
{
return TypedResults.Problem(response.Message);
}
return TypedResults.Empty;
}
Handler
public LoginUserHandler(UserManager<PublicUser> userManager, SignInManager<PublicUser> signInManager)
{
_userManager = userManager;
signInManager.AuthenticationScheme = IdentityConstants.BearerScheme;
_signInManager = signInManager;
}
public async Task<BaseResponse> Handle(LoginUserCommand request, CancellationToken cancellationToken)
{
var response = new BaseResponse();
var user = await _userManager.FindByNameAsync(request.Username);
if (user == null)
{
response.Success = false;
response.Message = "Login Failed";
return response;
}
var result = await _signInManager.PasswordSignInAsync(user, request.Password, false, true);
if (!result.Succeeded)
{
response.Success = false;
response.Message = "Login Failed";
}
return response;
}
I'm hoping to map this to a custom class so I can strongly type the API response in the Swagger definition.
When using PasswordSignInAsync
from a SignInManager
, the result is a SignInResult
which tells me if the sign in succeeded or failed but doesn't actually containt the details like the access token. The token and other info is stored in AccessTokenResponse
, which appears to just be stored in the context. My question is, how can I intercept the AccessTokenResponse
in order to map it to a custom class? Other than that, this implementation is working well.
When calling PasswordSignInAsync
from an API method, it seems like the AccessTokenResponse
is already embedded in the response without me doing anything, so I'm unsure how I would access it.
Controller Method (using Mediatr)
[HttpPost("Login")]
[AllowAnonymous]
public async Task<Results<Ok<AccessTokenResponse>, EmptyHttpResult, ProblemHttpResult>> Login(LoginUserCommand command)
{
var response = await Mediator.Send(command);
if (!response.Success)
{
return TypedResults.Problem(response.Message);
}
return TypedResults.Empty;
}
Handler
public LoginUserHandler(UserManager<PublicUser> userManager, SignInManager<PublicUser> signInManager)
{
_userManager = userManager;
signInManager.AuthenticationScheme = IdentityConstants.BearerScheme;
_signInManager = signInManager;
}
public async Task<BaseResponse> Handle(LoginUserCommand request, CancellationToken cancellationToken)
{
var response = new BaseResponse();
var user = await _userManager.FindByNameAsync(request.Username);
if (user == null)
{
response.Success = false;
response.Message = "Login Failed";
return response;
}
var result = await _signInManager.PasswordSignInAsync(user, request.Password, false, true);
if (!result.Succeeded)
{
response.Success = false;
response.Message = "Login Failed";
}
return response;
}
I'm hoping to map this to a custom class so I can strongly type the API response in the Swagger definition.
Share Improve this question edited Nov 20, 2024 at 20:54 SpicyCatGames 1,7461 gold badge18 silver badges34 bronze badges asked Nov 19, 2024 at 21:31 Matt MacDonaldMatt MacDonald 112 bronze badges1 Answer
Reset to default 0We can choose to generate a JWT token ourselves, use JwtSecurityTokenHandler to generate an access token, and return it to the client. This method does not rely on the externally stored AccessTokenResponse, so that we can directly control the entire login process.
[HttpPost("Login2")]
public async Task<IActionResult> Login2([FromBody] LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.Username);
if (user == null)
{
return Unauthorized("Invalid Username or Password.");
}
var result = await _signInManager.PasswordSignInAsync(user, model.Password, false, false);
if (!result.Succeeded)
{
return Unauthorized("Invalid Username or Password.");
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("Your_Secret_Key_Here_Your_Secret_Key_Here");
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Name, user.UserName)
}),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var jwtToken = tokenHandler.WriteToken(token);
var customResponse = new CustomResponse
{
AccessToken = jwtToken,
ExpiresIn = 3600 // 1 hour
};
return Ok(customResponse);
}
}
internal class CustomResponse
{
public string AccessToken { get; set; }
public string RefreshToken { get; set; }
public long ExpiresIn { get; set; }
}
本文标签:
版权声明:本文标题:ASP.NET Core Authentication - how to intercept AccessTokenResponse from SignInManager.PasswordSignInAsync - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742397098a2467148.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论