使用另一种身份验证方法进行外部 api 调用

2024-02-21

我有一个带有 MVC 的 Web API 应用程序。当用户使用网站时,身份验证和授权当前由我使用的全局表单身份验证自动处理,在 Web.config 中配置如下:

<authentication mode="Forms">
  <forms loginUrl="~/Login" slidingExpiration="true" timeout="1800" defaultUrl="/"></forms>
</authentication>
<authorization>
  <deny users="?" />
</authorization>

这可确保只有登录的用户才能访问该网站并调用 API。

但我还有一个外部 Windows 客户端,我想为其使用另一种身份验证方法。在没有表单身份验证的测试中,我设置了一个自定义 AuthorizeAttribute,可以在控制器中使用它,如下所示:

[ApiAuth]
public IEnumerable<string> Get() {
    // Return the resource
}

AuthorizeAttribute 看起来像这样:

public class ApiAuthAttribute : AuthorizeAttribute {
    public override void OnAuthorization(HttpActionContext context) {
        // Authenticate the request with a HMAC-based approach
    }
}

这在孤立的情况下工作得很好,但我不知道如何允许这两种身份验证方法。如果表单身份验证不起作用(或相反,无论起作用),我希望将 ApiAuth 作为后备,但如果我应用 [ApiAuth] 属性,则仅使用该属性,普通用户无法访问 api。

那么,如何使用多种身份验证方法,要么使用其中一种方法作为另一种方法失败时的后备方法,要么配置服务器,以便 Windows 客户端可以通过 MVC 应用程序以外的其他方式调用 API,同时仍然保持相同API 调用对两种类型的客户端都可用吗?

谢谢。


Edit:我可能采取的一种方法是让 Windows 客户端使用表单 auth 进行身份验证(类似于this https://stackoverflow.com/a/1879216/4688606),但它看起来很像黑客,我宁愿使用其他方法。


FormAuthentication可以通过多种方式实现。在过去,我们使用表单验证票 https://stackoverflow.com/a/38975468/296861.

现在,您可以通过 Owin Middleware 使用基于声明的身份验证,它基本上是 ASP.Net Identity 的精简版本。

在您对内部用户进行身份验证后ApiAuth属性,您创建主体对象。

网页配置

你不应该使用<authorization>ASP.Net MVC 中的标记。相反,你想使用Filter.

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

ApiAuth属性

public class ApiAuthAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext context)
    {
        // Authenticate the request with a HMAC-based approach

        // Create FormAuthentication after custom authentication is successful
        if (!HttpContext.Current.User.Identity.IsAuthenticated)
        {
            User user = new User {Id = "1234", UserName = "johndoe", 
                 FirstName = "John", LastName = "Doe"};

            // This should be injected using IoC container. 
            var service = new OwinAuthenticationService(
                 new HttpContextWrapper(HttpContext.Current));
            service.SignIn(user);
        }
    }
}

验证

public class User
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public interface IAuthenticationService
{
    void SignIn(User user);
    void SignOut();
}

public class OwinAuthenticationService : IAuthenticationService
{
    private readonly HttpContextBase _context;
    private const string AuthenticationType = "ApplicationCookie";

    public OwinAuthenticationService(HttpContextBase context)
    {
        _context = context;
    }

    public void SignIn(User user)
    {
        IList<Claim> claims = new List<Claim>
        {
            new Claim(ClaimTypes.Sid, user.Id),
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.GivenName, user.FirstName),
            new Claim(ClaimTypes.Surname, user.LastName),
        };

        /*foreach (Role role in user.Roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role.Name));
        }*/

        ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);

        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignIn(identity);
    }

    public void SignOut()
    {
        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignOut(AuthenticationType);
    }
}

启动.cs

[assembly: OwinStartup(typeof(YOUR_APPLICATION.Startup))]
namespace YOUR_APPLICATION
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Account/Login")
            });
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用另一种身份验证方法进行外部 api 调用 的相关文章

  • ASP.NET MVC 多线程

    我想在我的 asp net mvc 应用程序中实现这样的逻辑 user clicks a button gt server executes some time consuming logic in 15 threads i get dat
  • 使用 401 发送消息:Asp.net Web-api

    我在 ASP NET Web API 中 在登录方法中 我根据数据库检查用户 密码 如果它们不匹配 我将返回 401 状态代码以及invalid user or password method like var content new St
  • 实施令牌认证

    在我的网页中实施令牌身份验证必须遵循哪些步骤 任何摘要或链接将不胜感激 我想实现类似于 Facebook 或 Google 的功能 首次客户端登录并接收令牌 然后在下一步操作中使用它 我还阅读了有关 OAuth 的内容 但我不想让第三方访问
  • 自定义WebApi授权数据库调用

    我正在尝试确定我编写的自定义授权属性是否确实是一个好主意 Scenario假设我们有一系列商店 每个商店Store有一个主人 只有商店的所有者才能对商店进行CRUD操作 除了具有Claim这基本上超越了所有权要求 并表示他们可以在任何商店上
  • 有没有办法在 Blazor 中进行外部身份验证而不使用数据库?

    所以本质上我有一个 Blazor 服务器端应用程序 我正在尝试使用 Azure AD SAML 添加外部身份验证 我在用Sustainsys Saml2 AspNetCore2用于外部身份验证的包 我不太熟悉 ASP NET 或 Blazo
  • 基于 Web.Config 使用的 GAC 程序集版本

    Good Day 我有一个在 GAC 中使用自定义程序集的项目 为了能够使用它 我在中添加了对我的项目的引用 C WINDOWS Microsoft NET assembly GAC MSIL JOHN CommonLib v4 0 1 0
  • 在 Foreach 或 For 循环中使用 EditorFor (ASP.NET MVC + RAZOR)

    我目前正在实施一个家谱我的 ASP NET MVC 项目中的系统 为了设置家庭成员之间的关系 我需要每行显示两个 ComboBox DropDownList 来定义一个成员与另一个成员之间的关系 首先我将分享我的代码 然后我将解释到目前为止
  • iOS 相互认证

    我正在尝试在 IOS 5 中实现相互身份验证 但遇到了麻烦 NSUnderlyingError Error Domain kCFErrorDomainCFNetwork Code 1200 An SSL error has occurred
  • 即使通过 ssl,在 ViewState 中存储信用卡和定价信息是否安全?

    我有一个带有私有属性的页面 该页面在视图状态中存储信用卡对象和购物车对象 以便我可以在回发期间维护对它们的引用 顺便说一句 涉及的页面将使用 SSL 这安全吗 我不会在视图状态中存储敏感信息 ever 通过这样做 您将安全性委托给浏览器的实
  • VS 2010 Web应用程序中的ASP.NET Web Api CRUD操作

    我尝试在 VS 2010 Web 应用程序中进行 ASP NET Web Api CRUD 操作 但为什么结果没有从源表返回所有整行 这是我的代码 路线 Globax asax protected void Application Star
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 在多个网页(.cshtml 文件)中使用 Razor @functions

    我有以下功能 我希望可用于我的 asp net 网页 2 应用程序中的多个 cshtml 视图 如何使该功能可用于应用程序中的任何视图 而不是仅一个视图 functions public bool DisplayButton String
  • MVC 音频控制从字节播放歌曲

    我将歌曲作为 bytes 存储在数据库中 我如何在
  • 设置 runat=server 时输入名称和 id 发生变化

    在我的表单中 我需要插入 文本 类型的不同输入 输入必须是带有名称和 ID 的 html 控件 因为我将此表单发送到外部网址 对于验证 我在所有输入中执行 runat server 然后我可以使用 requiredfieldvalidato
  • 关于实体框架上下文生命周期的问题

    我对 ASP NET MVC 应用程序中实体框架上下文的所需生命周期有一些疑问 让上下文在尽可能短的时间内保持活动状态不是最好的吗 考虑以下控制器操作 public ActionResult Index IEnumerable
  • ASP.NET预编译的优点是什么?

    使用 Aspnet compiler exe 代替通过 Visual Studio 进行的传统发布有多有用 那么资源 resx 文件又如何呢 与简单的 xcopy 相比 预编译有两个主要优点 文件系统不会包含所有代码 aspx文件和后面的所
  • 序列包含多个元素

    我在通过 Linq 获取 RhsTruck 类型的列表并显示它们时遇到一些问题 RhsTruck 只有属性 品牌 型号 序列号 等 RhsCustomer 具有 CustomerName CustomerAddress 等属性 我不断收到错
  • 单元测试:创建“模拟”请求来模拟 MVC 页面请求

    如何为我的 asp net mvc 应用程序创建模拟请求以进行单元测试 我有什么选择 我在我的操作中使用 FormsCollection 因此我也可以模拟表单输入数据 您只需创建 FormCollection 的新实例并在其中添加数据即可
  • 同时从2个表中删除?

    我正在使用 asp net 和 sql 服务器 我有 2 个表 类别和产品 在产品表中 我的categoryId 为FK 我想要做的是 当我从类别表中删除类别时 我希望该类别中的所有产品都将在产品表中删除 如何才能做到这一点 我更喜欢使用存
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默

随机推荐

  • 没有名为 pyVim 的模块

    我正在使用 python 3 7 5 运行 Catalina MacOS 我正在尝试运行 ansible 脚本来安装虚拟机 这需要 python gt 2 6 和 PyVmomi 我已经通过 pip 安装了 PyVomi 和 pyVim 两
  • 如何在同一视图控制器上呈现表格视图和二维码扫描仪?

    我想要实现的目标是让屏幕的下半部分成为活动的二维码扫描仪 而屏幕的另一半成为表格视图 每当我扫描二维码时 它都会检查表格视图是否匹配并突出显示它 我需要用什么来实现这一点 我使用以下 cocoapod 作为二维码 https cocoapo
  • 适用于 Android 的心率传感器 API

    谷歌已经发布了有关可穿戴设备的API 由于许多智能手表制造商都声称他们有心率传感器 我想知道 android 是否为其发布了 api 我检查了网络并没有找到任何东西 有谁对可穿戴设备开发感兴趣并且知道这件事吗 Thanks 截至目前 这些
  • 如何在角度4中使用renderer2动态追加子项

    我是 Angular 4 的新手 需要使用 html 列表在 child 下添加 child Component selector my app template div ul root ul div export class App im
  • 动态委托给最小的 api

    各位程序员大家好 基本上 我想将动态构建的委托传递给最小的 api MapGet 或 MapPost 方法 这是构造委托的方法 private static Delegate GetDelegate Type type MethodInfo
  • Xamarin Forms WebView 检查网站地址何时更改

    我有以下代码在我的 Xamarin Forms 跨平台应用程序中设置 WebView ReportsListWebView new WebView VerticalOptions LayoutOptions FillAndExpand Ho
  • geocoder.getFromLocationName 仅返回 null

    这两天我快要疯了IllegalArgumentException当尝试从地址中获取坐标 甚至反向获取经度和纬度地址时 我在 Android 代码中收到错误 这是代码 但我看不到错误 它是一个标准代码片段 很容易在 Google 搜索中找到
  • Mercurial:远程:中止:这里没有 Mercurial 存储库(未找到 .hg)!

    all 我已经寻找这个问题很长时间并尝试了不同的方法 我想仅通过 SSH 在服务器上维护我的代码 但是当我运行这个时 sudo hg clone v ssh carl hostname home carl Java Projects pet
  • 20hz-20000hz 巴特沃斯滤波爆炸

    我想过滤掉 20 Hz 20000 Hz 之外的所有内容 我正在使用巴特沃斯滤波器 from scipy io import wavfile from scipy import signal import numpy sr x wavfil
  • Javascript 字符串大小限制:对我来说是 256 MB - 所有浏览器都一样吗?

    我很好奇我能在 Javascript 中获得的最大字符串长度是多少 今天我在 Windows 7 中运行的 Firefox 43 0 1 上亲自测试了它 我能够构造一个具有长度的字符串2 28 1 但是当我尝试创建一个多一个字符的字符串时
  • C# ImageFormat 转字符串

    我怎样才能获得人类可读的字符串 即图像格式本身 来自系统 绘图 图像格式目的 我的意思是如果我有ImageFormat Png是否可以将其转换为 png 字符串 EDIT 我在这里看到一些误解 这是我的代码 Image objImage I
  • 如何检测是否在osgi容器中运行

    我有一个 OSGi 包 也可以在纯 Java 进程中运行 我需要能够判断捆绑包是否已加载到 OSGi 系统中 我怎样才能做到这一点 如果没有 OSGi 标准方法来执行此操作 我将采用 Eclipse Equinox 特定的方法 将 Bund
  • Safari 11 X-XSRF-TOKEN 刷新后未更新

    最近 Mac OSX 上的 Safari 11 发布 此更新导致我们的 Web 应用程序与请求标题上的 XSRF 结合出现问题 我将尝试以逻辑方式描述问题 好的情况应该是这样的 当用户想要登录时 他会收到服务器的响应 其中包含包含 XSRF
  • 如何使用 React 和表单来获取选中的复选框值的数组?

    我正在尝试为我的投资组合网站构建一个过滤器 复选框可让您选择一种技术 react redux jquery 等 来显示包含该技术的作品 因此 每次用户单击某个框时 我都想将值 JavaScript Redux React 等 添加到一个数组
  • 绿色线程是否等于“真实”线程

    我从以下位置获取了示例代码理解 eventlet wsgi server https stackoverflow com questions 8509209 unterstanding eventlet wsgi server from e
  • 使用 CSS 更改悬停时的文本颜色

    我已经搜索过 但找不到与我遇到的这个问题相关的任何内容 我多年来一直试图解决这个问题 但似乎无法做到 我有一个 div 里面有文本和图像 我希望当我将鼠标悬停在 div 内的任何位置时 div 内的所有文本和背景都会改变颜色 我已经做到了底
  • 电视指南列表 API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无法从 Apple 开发者中心删除 App ID

    我已经看到 Apple 更改了 iOS 开发中心的证书 标识符和配置文件页面 并在堆栈上阅读此问题 答案 从开发者连接中删除应用程序 ID https stackoverflow com questions 996477 removing
  • 如何使用 ajax get 或 post 在 mvc 中使用参数将数据从视图传递到控制器

    我正在尝试使用 ajax 将数据从视图传递到控制器操作方法 如下所示 我有一个用户的 Membership 实例 我使用 viewbag 从另一个控制器传递到下面的这个视图 有点像这样 ViewBag MyUser MyUser 现在我想使
  • 使用另一种身份验证方法进行外部 api 调用

    我有一个带有 MVC 的 Web API 应用程序 当用户使用网站时 身份验证和授权当前由我使用的全局表单身份验证自动处理 在 Web config 中配置如下