热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详解.NET实现OAuth2.0四种模式(2)密码模式

一、密码模式的认证流程密码模式是比较简单的一种模式,其认证流程如下图所示:二、受限资源设计OAuth2.0设计的目的是限制某些资源的访问࿰
一、密码模式的认证流程

密码模式是比较简单的一种模式,其认证流程如下图所示:

二、受限资源设计

OAuth2.0设计的目的是限制某些资源的访问,用户必须认证通过之后才能访问。我们在项目中加入一个简单的Controller,作为资源示例。

右击项目,添加一个Web API控制器类(v2.1),如下图所示:

我们把这个类命名为ValuesController,在这个类中只添加一个函数:

public IHttpActionResult Get()
{return Ok(new string[] { "value1", "value2" });
}

完成编译之后,我们可以在Postman中访问这个资源:

显然,这个资源并没有受到保护,任何人不经过授权都可以访问。如果要让这个资源在授权之后才能访问,做法非常简单,就是在函数的头上加上[Authorize]:

[Authorize]
public IHttpActionResult Get()
{return Ok(new string[] { "value1", "value2" });
}

这时候,如果我们再去访问这个资源时,将会被拒绝:

如果要想访问此资源,我们就需要通过认证。

三、密码模式实现

首先,在项目中加入一个名为Startup的类,其代码如下所示:

[assembly: OwinStartup(typeof(PasswordMode.Startup))]//让整个网站的入口为Startup这个类
namespace PasswordMode
{public class Startup{public void Configuration(IAppBuilder app){//配置OAuthConfigureOAuth(app);//配置网站路由等信息HttpConfiguration config = new HttpConfiguration();Register(config);//允许跨域访问app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);app.UseWebApi(config);}private void ConfigureOAuth(IAppBuilder app){OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,//允许http而非https访问TokenEndpointPath = new PathString("/token"),//访问host/token获取AccessTokenAccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),//AccessToken在30分钟后过期Provider = new AuthorizationServerProvider()//AccessToken的提供类};app.UseOAuthAuthorizationServer(OAuthServerOptions);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}private static void Register(HttpConfiguration config){config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });var jsonFormatter = config.Formatters.OfType().First();jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();}}
}

代码中的注释应该已经比较清楚。由于这个项目是一个空项目,没有加入任何API或MVC的特性,所以我们在Register函数中注册了这些属性。ConfigureOAuth函数是对OAuth2.0协议的配置,如果使用密码模式,就是按照上面代码中的配置。用户只需要输入用户名、密码,然后访问host/token这个地址,即可获取AccessToken。

下面是AuthorizationServerProvider类的实现代码:

public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){context.Validated();}public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){//允许跨域访问context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });//获取用户传入的用户名和密码string UserName = context.UserName;string Password = context.Password;//通过查数据库,判断用户名和密码是否正确//以下只是一个示例,用户名必须以test开头if (!UserName.StartsWith("test")){context.SetError("invalid_grant", "用户名或密码不正确");return;}//以下即为认证成功//通过查数据库,得到一些用户的信息int userid = 13;string role = "管理员";string scope = "权限1,权限2";var identity = new ClaimsIdentity(context.Options.AuthenticationType);identity.AddClaim(new Claim("userid", userid.ToString()));identity.AddClaim(new Claim("role", role));identity.AddClaim(new Claim("scope", scope));context.Validated(identity);}
}

我们先在上下文中获取用户名和密码,然后一般通过查数据库,判断此用户名和密码是否正确。如果不正确,认证就失败了。如果正确,我们可以查数据库,获取用户的角色、权限范围等信息。

完成上述代码的编写后,密码模式就完成了。(是不是很简单)

我们用Postman测试:

在返回结果中,我们看到了access_token,把它复制出来,用在资源的访问上:

四、部分访问限制

我们在上述的代码中可以发现,当我们拿到AccessToken之后,所有标注[Authorize]的资源都可以访问了。但实际上,我们的资源限制会更复制一些。例如我们只允许管理员身份的用户去访问,或者只允许某个时间之前注册的用户,或者像微信登录时询问的,获取昵称的权限、获取头像的权限等等。对于这种需求,我们可以在资源函数中进行处理。

首先,我们在认证通过时,通过查数据库,得到了一些用户的属性:

//通过查数据库,得到一些用户的信息
int userid = 13;
string role = "管理员";
string scope = "权限1,权限2";var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("userid", userid.ToString()));
identity.AddClaim(new Claim("role", role));
identity.AddClaim(new Claim("scope", scope));

我们可以在资源函数中根据这些属性进行判断,是否允许用户继续访问。例如我们的资源函数可以改成这样:

public IHttpActionResult Get()
{string userid = "";string role = "";string scope = "";foreach (Claim c in (this.User.Identity as ClaimsIdentity).Claims){switch (c.Type){case "userid":userid = c.Value;break;case "role":role = c.Value;break;case "scope":scope = c.Value;break;}}if (userid != "13" || role != "管理员" || !scope.Contains("权限1")){return Unauthorized();}return Ok(new string[] { "value1", "value2" });
}

这样的话,只有用户ID为13,并且角色为管理员,同时又具有权限1这个访问权限的用户,才能正常地获取资源。


推荐阅读
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 如何使用 `org.apache.tomcat.websocket.server.WsServerContainer.findMapping()` 方法及其代码示例解析 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • R语言中向量(Vector)数据类型的元素索引与访问:利用中括号[]和赋值操作符在向量末尾追加数据以扩展其长度
    在R语言中,向量(Vector)数据类型的元素可以通过中括号 `[]` 进行索引和访问。此外,利用中括号和赋值操作符,可以在向量的末尾追加新数据,从而动态地扩展向量的长度。这种方法不仅简洁高效,还能灵活地管理向量中的数据。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 本文介绍了如何在指定目录下创建 Conda 虚拟环境,并管理包的安装路径。通过使用 `conda create --prefix /home/you/yourPythonProject` 命令,用户可以在自定义路径中安装 Python 3.5 及其相关依赖,从而实现更加灵活的环境管理和资源分配。此外,文章还提供了详细的步骤和注意事项,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在Linux系统中避免安装MySQL的简易指南
    在Linux系统中避免安装MySQL的简易指南 ... [详细]
  • Git命令基础应用指南
    本指南详细介绍了Git命令的基础应用,包括如何使用`git clone`从远程服务器克隆仓库(例如:`git clone [url/path/repository]`)以及如何克隆本地仓库(例如:`git clone [local/path/repository]`)。此外,还提供了常见的Git操作技巧,帮助开发者高效管理代码版本。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • Cosmos生态系统为何迅速崛起,波卡作为跨链巨头应如何应对挑战?
    Cosmos生态系统为何迅速崛起,波卡作为跨链巨头应如何应对挑战? ... [详细]
  • SSL 错误:目标主机名与备用证书主题名称不匹配
    在使用 `git clone` 命令时,常见的 SSL 错误表现为:无法访问指定的 HTTPS 地址(如 `https://ip_or_domain/xxxx.git`),原因是目标主机名与备用证书主题名称不匹配。这通常是因为服务器的 SSL 证书配置不正确或客户端的证书验证设置有问题。建议检查服务器的 SSL 证书配置,确保其包含正确的主机名,并确认客户端的证书信任库已更新。此外,可以通过临时禁用 SSL 验证来排查问题,但请注意这会降低安全性。 ... [详细]
  • 本文详细探讨了在ASP.NET环境中通过加密数据库连接字符串来提升数据安全性的方法。加密技术不仅能够有效防止敏感信息泄露,还能增强应用程序的整体安全性。文中介绍了多种加密手段及其实施步骤,帮助开发者在日常开发过程中更好地保护数据库连接信息,确保数据传输的安全可靠。 ... [详细]
author-avatar
家宇珮禎忠全
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有