javascript - 如何将 JWT 身份验证与 Web API 集成?

标签 javascript c# asp.net jwt

我在将 JWT 与我的 Web API 集成时遇到问题。我尝试按照此操作 tutorialexample

这看起来很简单,但我在将其与我的项目集成时遇到了困难。您应该知道我有一堆 .aspx(Web 表单)文件来制作我的网站。该网站正在使用 javascript (Ajax) 使用我的 Web API。我已经安装了 jose-jwt 包,因此我可以在我的代码中使用它。

服务器端

WebApiConfig.cs:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "defaultApiRoutes",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: new { id = @"\d+" }   // Only matches if "id" is one or more digits.
            );

            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        }
    }

我在“请求” Controller 中的操作之一的示例:

[HttpPost]
        [ActionName("createRequest")]
        public IHttpActionResult createRequest(Request request)
        {
            if (userIsAuthorized) // I am guessing that for each action there will be this kinda condition to check the token of the user
            if (ModelState.IsValid) {
                using (SqlConnection connection = WebApiApplication.reqeustConnection("ConStrMRR")) {
                    using (SqlCommand command = new SqlCommand("createRequest", connection)) {
                        try {
                            command.CommandType = CommandType.StoredProcedure;
                            command.Parameters.Add(new SqlParameter("@status_id", request.StatusID));
                            command.Parameters.Add(new SqlParameter("@patient_firstname", request.PatientFirstName));
                            command.Parameters.Add(new SqlParameter("@patient_lastname", request.PatientLastName));
                            command.Parameters.Add(new SqlParameter("@patient_url", request.PatientURL));
                            command.Parameters.Add(new SqlParameter("@facility", request.Facility));
                            connection.Open();
                            int request_id = (int)command.ExecuteScalar();
                            return Ok(request_id);
                        } catch (Exception e) {
                            throw e;
                        } finally {
                            connection.Close();
                        }
                    }
                }
            }
            return Content(HttpStatusCode.BadRequest, "Request has not been created.");
        }

客户端

创建请求.js

$.ajax({
            url: "http://" + window.myLocalVar + "/api/requests/createRequest",
            type: "POST",
            dataType: 'json',
            contentType: 'application/json',
            data: request,
            success: function (request_id, state) {
                    console.log(request_id);
            },
            error: function (err) {
                if (err) {
                    notyMessage(err.responseJSON, 'error');
                }
            }
        });      

我猜测之前的请求将在“成功”函数之后更新为以下内容:

beforeSend: function(xhr)
              {
                xhr.setRequestHeader("Authorization", "Bearer " + localStorage.getItem('token'));
              },

我的登录页面如下所示:

<body id="cover">

<div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="login-panel panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">Please Sign In</h3>
                </div>
                <div class="panel-body">
                    <div align="center" style="margin-bottom: 50px;"><img class="img-responsive" src="../img/logo.jpg"/></div>
                    <form role="form" runat="server">
                        <fieldset>
                            <div class="form-group">
                                <asp:TextBox ID="usernameTextBox" CssClass="form-control" runat="server" placeholder="Username"></asp:TextBox>
                            </div>
                            <div class="form-group">
                                <asp:TextBox ID="passwordTextBox" CssClass="form-control" runat="server" placeholder="Password" TextMode="Password"></asp:TextBox>
                            </div>
                            <div class="checkbox">
                                <label>
                                    <asp:CheckBox ID="rememberMeCheckBox" runat="server"/>Remember Me
                                </label>
                            </div>
                            <!-- Change this to a button or input when using this as a form -->
                            <asp:Button CssClass="btn btn-primary btn-block" Text="Login" ID="Login" runat="server"/>
                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

我在将 JWT 身份验证与我的代码集成时遇到困难。您能帮忙吗?

谢谢!

最佳答案

所以,你将拥有:

  1. 一个 Web API 服务器(“API”)
  2. 一个 Web 表单应用程序(“客户端”)

Web API 服务器

API 将受 JWT 保护。 API 的每个客户端都应在 HTTP header (承载 token )中提供 JWT。该 JWT 将由身份提供商在身份验证时提供。

Web API 需要某种中间件来从请求中获取 JWT token ,对其进行验证(验证受众、颁发者、过期和签名)并设置对请求有效的 ClaimsPrincipal。这样您就可以使用 .Net 标准授权属性和过程,例如:

[Authorize] // requires the user to be authenticated
public IActionResult SomeProtectedAction()
{
}

如果您的 Web API 用于 ASP.Net Core,则可以使用 Microsoft.AspNetCore.Authentication.JwtBearer为此,配置如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    var options = new JwtBearerOptions
    {
        Audience = "[Your API ID]",
        Authority = $"[URL for your identity provider]/",
        // certificate public keys will be read automatically from
        // the identity provider if possible
        // If using symmetric keys, you will have to provide them
    };
    app.UseJwtBearerAuthentication(options);

}

使用 OWIN 的常规 ASP.Net 应用程序可以使用 Microsoft.Owin.Security.ActiveDirectory包,配置代码如下:

public void Configuration(IAppBuilder app)
{
    var issuer = $"[url to identity provider]/";
    var audience = "[your API id];

    app.UseActiveDirectoryFederationServicesBearerAuthentication(
        new ActiveDirectoryFederationServicesBearerAuthenticationOptions
        {
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudience = audience,
                ValidIssuer = issuer
                // you will also have to configure the keys/certificates
            }
        });

客户端

您的客户端应用程序将是一个网络表单应用程序。用户登录后(通常通过将用户重定向到身份提供商的登录页面),您将取回访问 token 。您可以将 token 存储在客户端(本地存储)中,并在调用 API 时使用它,如您所示:

beforeSend: function(xhr) {
    xhr.setRequestHeader("Authorization", "Bearer " + localStorage.getItem('token'));
},

关于javascript - 如何将 JWT 身份验证与 Web API 集成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40389279/

相关文章:

javascript - 如何使用 localStorage 中的数据渲染 React 组件?

c# - 从 IIS 应用程序池运行应用程序

c# - ...由于其保护级别 c#/asp.net 而无法访问

javascript - 单个redis客户端连接是否支持并发读写?

javascript - mozrepl:遍历所有 firefox 窗口中的所有选项卡

c# - 可以使子类仅通过静态属性实例化

c# - 未声明 XML 签名元素

Javascript 获取选定值返回 'undefined'

asp.net - UpdatePanel 中未修改的 DropDownList 导致 FireFox 中的事件验证错误

javascript - 使用 iMacros 向下滚动到页面底部