Reputation: 495
My main application delegates authentication to an AuthService application, asking it to authenticate against an Identity Provider through OpenId Connect and return a token.
[Authorize]
[HttpGet("Login")]
public IActionResult Login()
{
return Ok(
{
Token = ?
}, OpenIdConnectDefaults.AuthenticationScheme);
}
I have an API method with the [Authorize]
attribute. The user is prompted to login if not already authenticated and then the method runs. My question is can I access the token from there so I can pass it in the response?
Is there a simple way to achieve this?
Upvotes: 0
Views: 746
Reputation: 495
Here's what I've come up with after looking through the suggestions here:
[AllowAnonymous]
[HttpGet("Login")]
public IActionResult Login()
{
return Challenge(new AuthenticationProperties
{
RedirectUri = $"{HttpContext.Request.PathBase.Value}/GetToken"
}, OpenIdConnectDefaults.AuthenticationScheme);
}
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
[HttpGet("GetToken")]
public IActionResult GetToken()
{
var token = _contextAccessor.HttpContext.GetTokenAsync(OpenIdConnectDefaults.AuthenticationScheme, "id_token").Result;
return Ok(new
{
Token = token
});
}
I combined two APIs. From the perspective of the client app it makes a call to a Login API and gets the token as the result. Behind the scenes the Login API redirects to a second API to get and return the token.
UPDATE:
Revisting this after a while in case anyone sees this. I don't remember exactly how, but I think there was a problem with above approach for me.
In the end I used the OnSignedIn
CookieAuthenticationHandler
event to intercept the token and returned it with the response in a Cookie. The Login API still returns a Challenge
request.
Upvotes: 0
Reputation: 116
you must get a token to access the Authorize attribute method.
reference this
Upvotes: 0
Reputation: 1430
The [Authorize] attribute you are putting on the method means that you are restricting access to the method to authorised users only, so putting that attribute on a Login method makes no sense, as you would have to be authenticated to call it.
What you are looking for is
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
}
[Authorize]
public ActionResult Logout()
{
}
}
As for how to generate a token, you need to have an identity provider to take a username and password, validate it and create a token that has roles and privs.
I would suggest having a look at Identity Server 4 to generate tokens.
For info on how to connect it to OpenID see Adding User Authentication with OpenID Connect
Upvotes: 0
Reputation: 1368
You can get that information injecting a IHttpContextAccessor
service in the controller and defining the service in the startup.cs class
public class HomeController
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
//check the _httpContextAccessor.HttpContext object for information about the already logged user
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
Upvotes: 1