簡體   English   中英

ASP.Net Web API - 從 ASP.NET MVC 項目生成不記名令牌

[英]ASP.Net Web API - Generate Bearer Token from ASP.NET MVC Project

對不起,如果這個問題措辭不當,我是身份驗證的新手。

我有一個 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);
    }
}

謝謝,如果有任何有用的進一步信息,請告訴我。

我之前實施過的一個要考慮的選項是在從 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...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM