user3167162
user3167162

Reputation: 495

How to return auth Token from .Net Core [Authorize] method

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

Answers (4)

user3167162
user3167162

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

Homura Lin
Homura Lin

Reputation: 116

you must get a token to access the Authorize attribute method.

reference this

Upvotes: 0

Xavier
Xavier

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

Rod Ramírez
Rod Ramírez

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

Related Questions