NET Core 3.1 MVC 授权/身份验证,使用在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)

2024-03-24

我有3个项目:

  1. Net Core 3.1 MVC 项目。
  2. 使用 JWT 身份验证的 Net Core 3.1 Web Api 项目 --> 通过实体框架连接到数据库
  3. (Xamarin 应用程序还使用 Web API 进行身份验证和数据检索)。

我不想从两个项目(1,2)分别连接到同一个数据库(感觉不是一个好主意,如果我错了请纠正我,希望将数据库增删改查操作包含在Web API中)。

我想在Web Api项目中进行身份验证并将令牌传递给Net Core MVC项目。

我不知道如何使用令牌为 MVC 授权该用户 项目,以便可以根据用户的角色访问控制器 等等。基本上使用令牌在MVC项目中登录该用户 在Web api中获取。这是否可能或正确的方法?任何 请帮助?

MVC项目 Startup.cs 类

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {            
            // add for razor pages and refresh without rebuilding
            services.AddRazorPages().AddRazorRuntimeCompilation();


            // add httpClient
            services.AddHttpClient();

            // start auth jwt
            services.AddSession(options => {
                options.IdleTimeout = TimeSpan.FromMinutes(1);
            });
            //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            //Provide a secret key to Encrypt and Decrypt the Token
            var SecretKey = Encoding.ASCII.GetBytes
                 ("mySecretKeyForAuthenticationAndAuthorization");
            //Configure JWT Token Authentication
            services.AddAuthentication(auth =>
            {
                auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(token =>
            {
                token.RequireHttpsMetadata = false;
                token.SaveToken = true;
                token.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
            //Same Secret key will be used while creating the token
            IssuerSigningKey = new SymmetricSecurityKey(SecretKey),
                    ValidateIssuer = true,
            //Usually, this is your application base URL
            ValidIssuer = "https://myAzureWebAPi.azurewebsites.net",
                    ValidateAudience = true,
            //Here, we are creating and using JWT within the same application.
            //In this case, base URL is fine.
            //If the JWT is created using a web service, then this would be the consumer URL.
            ValidAudience = "https://mylocalhost/",
                    RequireExpirationTime = true,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                };
            });
            // end auth jwt


            // add for roles authorization
           services.AddAuthorization(config =>
           {
               config.AddPolicy(Policies.Admin, Policies.AdminPolicy());
               config.AddPolicy(Policies.Client, Policies.ClientPolicy());
           });

            services.AddControllersWithViews();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            //add for jwt
            app.UseCookiePolicy();
            app.UseSession();
            //Add JWToken to all incoming HTTP Request Header
            app.Use(async (context, next) =>
            {
                var JWToken = context.Session.GetString("JWToken");
                if (!string.IsNullOrEmpty(JWToken))
                {
                    context.Request.Headers.Add("Authorization", "Bearer " + JWToken);
                }
                await next();
            });


            app.UseRouting();


            // added for jwt
            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(    
                     name: "default",
                     pattern: "{area=Client}/{controller=LoginPage}/{action=Index}/{id?}");
            });
        }
    }

MVC LoginPageController.cs

    [Area("Client")]
        public class LoginPageController : Controller
        {
            private readonly IHttpClientFactory _clientFactory;
            public LoginPageController(IHttpClientFactory clientFactory)
            {
                _clientFactory = clientFactory;
            }
      
            public IActionResult Index()
            {
                return View();
            }
    
    
            [HttpPost]
            public async Task<IActionResult> Login([Bind] LoginModel loginModel)
            {
                var client = _clientFactory.CreateClient();
                //var client = new HttpClient();
    
                try
                {
                    var json = JsonConvert.SerializeObject(loginModel);
                    var content = new StringContent(json, Encoding.UTF8, "application/json");
    
                    var outcome = await client.PostAsync("https://<AzureWebAPiUrl>/api/accounts/login", content);
    
                    if (outcome!= null && outcome.IsSuccessStatusCode)
                    {
                        var jsonResult = await outcome.Content.ReadAsStringAsync();
                        var token = JsonConvert.DeserializeObject<Token>(jsonResult);
    
                        Console.WriteLine(token.user_role);
    
                        // store token in a session
                        HttpContext.Session.SetString("JWToken", token.access_token);
    
                        // Here is the problem, once I have the token how do I make this user be 
 //authenticated in the mvc project so that the [Authorize[Role = "someRole"] on controllers works
                    }
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
    
                return RedirectToAction("Index", "AdminDeals", new { area = "Admin"}); // only if role is admin
            }
        }

嘿,我有解决方案,请参阅下面的点

  1. 首先您需要添加身份验证。public void ConfigureServices(IServiceCollection services)
           services.AddSession();
           services.AddAuthentication(options =>
           {
                 options.DefaultAuthenticateScheme = >JwtBearerDefaults.AuthenticationScheme;
                 options.DefaultAuthenticateScheme = >JwtBearerDefaults.AuthenticationScheme;
                 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
           })
       // Adding Jwt Bearer
       .AddJwtBearer(options =>
       {
           options.SaveToken = true;
           options.RequireHttpsMetadata = false;
           options.TokenValidationParameters = new TokenValidationParameters()
           {
               ValidateIssuer = true,
               ValidateAudience = true,
               ValidAudience = Configuration["JWTConfig:ValidAudience"],
               ValidIssuer = Configuration["JWTConfig:ValidIssuer"],
               IssuerSigningKey = new >SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWTConfig:Secret"]))
           };
       });
  1. 之后,您必须使用会话来存储身份验证令牌,并且在此令牌中,您必须对角色列表的令牌组合进行加密,无论角色想要传递授权。Here i have used JWT Bearer token
  2. 使用此会话您必须配置public void Configure(IApplicationBuilder app, IWebHostEnvironment env)用于使用标头身份验证的startup.cs 文件。
   app.UseSession();
   app.Use(async (context, next) =>
   {
      var token = context.Session.GetString("Token");
      if (!string.IsNullOrEmpty(token))
      {
          context.Request.Headers.Add("Authorization", "Bearer " + token);
      }
      await next();
   });
  1. 然后你必须添加你的控制器
   [Authorize(Roles = "Employee,Student")]
   public ActionResult Leave()
   {
         // your code here
   }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NET Core 3.1 MVC 授权/身份验证,使用在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT) 的相关文章

随机推荐

  • Scala-IDE 中工作表中的类导致错误

    只需在工作表中键入以下内容即可实例化一个类 注意 工作表是使用 文件 gt 新建 gt Scala 工作表 创建的 sc文件 不是普通文件 scala文件 并单击保存会导致虚假错误 鼠标移到 这条线上有多个标记 简单表达式的非法开头 符合预
  • 基于检查约束的分区修剪未按预期工作

    为什么下面的查询计划中包含表 events 201504 根据我的查询和该表的检查约束 我希望查询规划器能够完全修剪它 database d events 201504 Table public events 201504 Column T
  • Clojure WebSocket 应用程序的 nginx 产品设置

    我正在尝试部署我的第一个 Clojure WebSocket 应用程序 我想我已经很接近了 我在本地得到了很好的响应 看起来端点想要面对外界 当我运行时我看到端口是开放的netstat 但没有任何反应 我确信我的某些设置不正确nginx 我
  • 如何在 Vue.js 方法中使用外部 JavaScript 对象

    我正在尝试让 Stripe 与我的 Vue js 2 应用程序一起工作 出于 PCI DSS 原因 Stripe 要求其 Javascript总是从加载js stripe com https stripe com docs web setu
  • 我应该使用 URLDownloadToFile 吗?

    我正在寻找用 C 下载文件的最简单方法 在 Windows 上 URLDownloadToFile 听起来很棒 并且不需要我使用curl 或其他我不需要的胖库 这个函数有什么要求 它将在哪些 Windows 上运行 Thanks http
  • 基于 JavaScript 的开源客户端 2D 数据绘图?

    我想知道是否有任何使用 JavaScript 在客户端运行的 2D 图形绘制库 基本思想是 您可以在浏览器中放置一个绘图 用户可以更改 X 和 Y 比例和限制 放大和缩小等内容 而无需不断地从服务器重新加载网页 数据本身将通过 AJAX 获
  • 尝试在空对象引用上调用虚拟方法“androidx.navigation.NavGraph androidx.navigation.NavDestination.getParent()”

    我创建了一个 Android 应用程序 并从图库中添加了 导航抽屉活动 删除并重命名了菜单项 启动应用程序后 当我单击抽屉活动中的任何菜单项时 出现以下错误 java lang NullPointerException Attempt to
  • 布局位于状态栏和软键下方

    我不确定我是如何得到这个的 而且我找不到类似的东西 但我的软件导航和状态栏是在我的布局上绘制的 而不是我的布局适合它们之间 如何让我的布局绘制在它们之间而不是下面 Edit 看来这就是罪魁祸首 位于样式中
  • 为什么“change_protection”在将大量数据加载到 RAM 时会占用 CPU?

    我们建立了一个内存数据库 单个数据库占用约 100 150G RAMVec https doc rust lang org std vec struct Vec html 其填充如下 let mut result Vec with capa
  • 如何镜像 UIBezierPath?

    我有一个UIBezierPath我想得到它的镜像 我怎样才能做到这一点 Method for generating a path UIBezierPath myPath self generateAPathInBounds bounding
  • byte[] 转灰度 BitmapImage

    我从 128 x 128 双精度数组开始 然后将其转换为每个双精度值具有比例值的一维字节数组 然后我获取这个字节数组并将其转换为内存流 dataStream下面 并尝试将其放入BitmapImage像这样 imgScan Width 128
  • Android:启动时在后台进行应用程序登录

    我有一个VOIP应用程序 我需要在设备启动时在后台登录应用程序 目前我的应用程序的初始化已完成UI Active onCreate 我心里有以下几点 谁能帮我解答一下我的疑惑 服务设计是必须完成这个任务吗 Which Service Rem
  • Raphael JS 组合路径

    我对 SVG 和 Raphael 还很陌生 但我已经使用 Illustrator 多年了 所以我对其工作原理有一些假设 我想组合两个应该返回单个元素的路径 我需要制作一个对话气泡 但它实际上可以是任何东西 在这种情况下 我尝试制作两个rec
  • Linux 内核 dentry 和 inode

    是否可以从给定的 dentry 和 inode 构造绝对路径 谢谢大家 如果你有一个struct path 或者可以构造一个 看看 tomoyo 是如何做到这一点的 http lxr linux no linux v2 6 37 secur
  • 为什么 JavaScript 中的 Boolean() 这么慢?

    根据 ECMAScript 规范 两者一元逻辑 NOT 运算符 http www ecma international org ecma 262 5 1 sec 11 4 9 and the Boolean 功能 http www ecma
  • 从 Firebase 查询更新变量值?

    我目前正在尝试使用从 firebase 中提取项目的值once 并使用该值填充 varitemsList 但是 尽管 itemsList 已正确填充在once调用时 它在调用外部记录为未定义 我认为这可能与 Firebase 的异步特性有关
  • Kendo UI:TabStrip HtmlHelper 添加部分视图

    在 MVC 3 中的 Kendo UI 内部 我需要为每个选项卡添加部分视图作为该选项卡的内容 这是如何完成的 文档似乎没有显示任何方法 var partialData Html Partial Views Templates p myVi
  • 对象属性随分配变量的值动态变化

    由于我是新手 这可能是一个非常基本的问题 我正在从构造函数创建一个对象 我希望将对象的属性之一链接到变量 因此 如果变量值发生变化 属性的值也应该发生变化 示例 我正在使用kineticjs并从构造函数创建一个对象Rect 我想要房产的价值
  • 使用 Symfony 插件的 PhpStorm 中缺少 Twig 模板

    PhpStorm version 9 0 2 Symfony Plugin version 0 11 109 Symfony version 3 0 1 模板引用对于放置在下面的模板文件效果很好app Resources views但不适用
  • NET Core 3.1 MVC 授权/身份验证,使用在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)

    我有3个项目 Net Core 3 1 MVC 项目 使用 JWT 身份验证的 Net Core 3 1 Web Api 项目 gt 通过实体框架连接到数据库 Xamarin 应用程序还使用 Web API 进行身份验证和数据检索 我不想从