问题
I have a .NET MVC
and WEB API
project. I want to call the WEB API controllers
from javascript but I didn't find a way to send the token to my views. I want to add the bearer token
in Viewbag
variable, using the below code:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
//GetBearerToken doesn't exists
ViewBag.BearerToken = Request.GetOwinContext().GetBearerToken();
}
In _Layout.cshtml
, I added the folowing code to set Authorization
header for all ajax requests:
<script type="text/javascript">
window.token = '@Viewbag.BearerToken';
// Add Authorization header on ajax requests
if(window.token) {
(function setAjaxRequestsAuthorizationHeader(token) {
$.ajaxPrefilter(function onAjaxPrefilter(options) {
if (!options.beforeSend) {
options.beforeSend = function onBeforeSend(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
}
}
});
}(window.token));
window.token = null;
}
</script>
Below is my Startup configuration method:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
//app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext(AppDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: id => id.GetUserId<int>())
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
}
To get a token
I also tried (in the MVC Controller methods):
var token = new ClaimsPrincipal(User.Identity).Claims.FirstOrDefault(x => x.Type == "access_token")?.Value;
But the value of variable token is always null.
I have also inspected all claims values but I didn't find any possible token.
How can I send the token
to controller views
?
Solved
I solved the problem by doing the following steps:
In
Startup.Auth.cs
I added the folowing static property:public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
I have created an extension method for
ApplicationUser
class:public static async Task<ClaimsIdentity> GenerateUserIdentityAsync(this ApplicationUser user, UserManager<ApplicationUser, int> manager, string type) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); // Genereate Bearer token if (manager is ApplicationUserManager && type == DefaultAuthenticationTypes.ApplicationCookie) { var accessTokenFormat = Startup.OAuthOptions.AccessTokenFormat; if (accessTokenFormat != null) { IDictionary<string, string> data = new Dictionary<string, string> { ["userName"] = user.UserName }; AuthenticationProperties properties = new AuthenticationProperties(data); AuthenticationTicket ticket = new AuthenticationTicket(userIdentity, properties); var token = accessTokenFormat.Protect(ticket); userIdentity.AddClaim(new Claim("Access_Token", token)); } } return userIdentity; }
I modified the method
OnActionExecuting
to send token to the client:protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (Request.IsAuthenticated) { var identity = (ClaimsIdentity)User.Identity; ViewBag.BearerToken = identity.Claims.FirstOrDefault(x => x.Type == "Access_Token")?.Value; } }
In
Startup.Auth.cs
use the extension method created at step 2 when creatingIdentity
:OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie), getUserIdCallback: id => id.GetUserId<int>())
来源:https://stackoverflow.com/questions/48931314/how-to-send-bearer-token-to-views-in-asp-net-mvc-5