【问题标题】:ASP.Net Web API - Generate Bearer Token from ASP.NET MVC ProjectASP.Net Web API - 从 ASP.NET MVC 项目生成承载令牌
【发布时间】:2018-07-23 05:30:53
【问题描述】:

抱歉,如果这个问题措辞不当,我是身份验证新手。

我有一个 ASP.NET MVC 项目为我的 Web 前端提供服务,它使用 OWIN 和基于身份 cookie 的身份验证进行身份验证。这似乎与我的 Web API 无关。

我还有一个 ASP.NET Web API 项目,该项目也使用 OWIN 和基于身份令牌的身份验证进行身份验证,例如向 /Token 端点发出请求并获取可用于向 API 端点发出请求的不记名令牌。当使用通过 /Token 端点生成的不记名令牌通过邮递员调用时,这工作正常,但是当我想从 MVC 应用程序调用 API 时没有密码,我不能使用令牌端点生成一个令牌。

我的问题是我希望能够从经过身份验证的 ASP.NET MVC 应用程序向 ASP.NET Web API 发出请求,我将如何生成一个可以调用 Web API 的令牌?鉴于我有一个已通过身份验证的 ClaimsIdentity。

我的 MVC 项目的 Startup.Auth 是:

public partial class Startup 
{
    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<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.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, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });            
    }
}

我的 Web API 项目的 Startup.Auth 是:

public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Configure the application for OAuth based flow
        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);
    }
}

谢谢,如果有任何有用的进一步信息,请告诉我。

【问题讨论】:

    标签: asp.net asp.net-identity owin


    【解决方案1】:

    我之前实现过的一个要考虑的选项是在从 MVC 应用程序成功登录后从 API 检索令牌 - 使用在登录期间传入的相同凭据。以您喜欢的方式存储令牌(即在 ASP.NET 会话状态中),然后在您的应用程序中根据需要使用它。

    您的 MVC 应用程序登录控制器操作可能如下所示:

    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
    
    switch (result)
    {
        case SignInStatus.Success:
    
            BearerToken token;
    
            using (var httpClient = new HttpClient())
            {
                var tokenRequest =
                    new List<KeyValuePair<string, string>>
                        {
                            new KeyValuePair<string, string>("grant_type", "password"),
                            new KeyValuePair<string, string>("username", model.Email),
                            new KeyValuePair<string, string>("password", model.Password)
                        };
    
                HttpContent encodedRequest = new FormUrlEncodedContent(tokenRequest);
    
                HttpResponseMessage response = httpClient.PostAsync("https://YourWebApiEndpoint/Token", encodedRequest).Result;
                token = response.Content.ReadAsAsync<BearerToken>().Result;
    
                // Store token in ASP.NET Session State for later use
                Session["ApiAccessToken"] = token.AccessToken;
            }
    
            return RedirectToAction("SomeAction", "SomeController");
    }
    

    BearerToken 只是完整 API 令牌结构的定制类表示:

    public class BearerToken
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }
    
        [JsonProperty("token_type")]
        public string TokenType { get; set; }
    
        [JsonProperty("expires_in")]
        public string ExpiresIn { get; set; }
    
        [JsonProperty("userName")]
        public string UserName { get; set; }
    
        [JsonProperty(".issued")]
        public string Issued { get; set; }
    
        [JsonProperty(".expires")]
        public string Expires { get; set; }
    }
    

    从 MVC 应用程序中检索某些数据的示例调用可能如下所示:

    using (var httpClient = new HttpClient())
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Session["ApiAccessToken"].ToString());
    
        var response = httpClient.GetAsync("https://YourWebApiEndpoint/SomeController/SomeGetAction").Result;
    
        // Do something with response...
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-01
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      • 2014-10-06
      • 1970-01-01
      • 2020-06-03
      • 1970-01-01
      相关资源
      最近更新 更多