I'm using Owin and ASP.NET Identity to use OAuth tokens for securing my Web API methods. The token subsystem is set up as such:
var oauthOptions = new OAuthAuthorizationServerOptions()
{
TokenEndpointPath = new PathString("/Token"),
Provider = new SimpleAuthorizationServerProvider(),
AccessTokenFormat = new TicketDataFormat(app.CreateDataProtector(typeof(OAuthAuthorizationServerMiddleware).Namespace, "Access_Token", "v1")),
RefreshTokenFormat = new TicketDataFormat(app.CreateDataProtector(typeof(OAuthAuthorizationServerMiddleware).Namespace, "Refresh_Token", "v1")),
AccessTokenProvider = new AuthenticationTokenProvider(),
RefreshTokenProvider = new AuthenticationTokenProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
app.UseOAuthAuthorizationServer(oauthOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
It works great for requesting tokens based on username/password and then consuming those tokens. However, since the user is already authenticated when hitting the controller that renders the SPA, I would like to generate the token in my view and pass it on to the Javascript code, instead of having to log in again in the SPA.
So my question is: how do I manually generate my token so I can include it in my SPA view?
To get a token to call the downstream API, you inject the ITokenAcquisition service by dependency injection in your controller's constructor (or your page constructor if you use Blazor), and you use it in your controller actions, getting a token for the user ( GetAccessTokenForUserAsync ) or for the application itself ...
It enables users to verify their identity to websites, which then generates a unique encrypted authentication token. That token provides users with access to protected pages and resources for a limited period of time without having to re-enter their username and password.
You can generate access token inside a controller by calling OAuthBearerOptions.AccessTokenFormat.Protect(ticket)
and the code will look as the below:
private JObject GenerateLocalAccessTokenResponse(string userName) { var tokenExpiration = TimeSpan.FromDays(1); ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, userName)); var props = new AuthenticationProperties() { IssuedUtc = DateTime.UtcNow, ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration), }; var ticket = new AuthenticationTicket(identity, props); var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket); JObject tokenResponse = new JObject( new JProperty("userName", userName), new JProperty("access_token", accessToken), new JProperty("token_type", "bearer"), new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString()), new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()), new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString()) ); return tokenResponse; }
And you need to declare you OAuthBearerOptions
as static
property in class Startup.cs
But if you are looking to implement silent refresh for access token without requesting the user to login again, then you should consider implementing refresh token grant, do not do it like the way you suggested. You can read my detailed blog post on how to generate refresh tokens in SPA built with AngularJS.
Hope this answers your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With