ASP.NET Core跨站登录重定向的实现新姿势
前言
作为 .NET 程序员,痛苦之一是自从 ASP.NET 诞生之日起直到最新的 ASP.NET Core 都无法直接实现跨站登录重定向(比如访问 https://q.cnblogs.com ,跳转到 https://passport.cnblogs.com 进行登录),只能跳转到当前站点。
具体拿 ASP.NET Core 来说就是 CookieAuthenticationOptions.LoginPath
只能指定路径,不能指定包含主机名的完整 url ,ASP.NET Core 会在重定向时自动加上当前请求的主机名。
services.AddAuthentication() .AddCookie(options => { options.LoginPath = "/account/signin"; });
ReturnUrl 查询参数也只会包含路径,不包含完整的 url 。
为了解痛,在 ASP.NET 时代我们服用的解药要么是不用 ASP.NET 的登录跳转机制,要么通过专门的 UserController.Login Action 进行二次跳转,在 ASP.NET Core 时代我们改服了 Middleware 的解药,在专门的 Middleware 中进行跳转(也比较麻烦)。
昨天在阅读了 ASP.NET Core Authenticaion 的源码后,我们找到了一种新的解药 —— 修改 CookieAuthenticationEvents.OnRedirectToLogin
委托实现跨站登录重定向。
以下是新解药制作方法。
在 Startup.ConfigureServices 中给 AddCookie 添加如下的配置代码以使用修改后的 url 进行重定向:
services.AddAuthentication() .AddCookie(options => { var originRedirectToLogin = options.Events.OnRedirectToLogin; options.Events.OnRedirectToLogin = context => { return originRedirectToLogin(RebuildRedirectUri(context)); }; });
RebuildRedirectUri 的实现代码如下:
private static RedirectContext<CookieAuthenticationOptions> RebuildRedirectUri( RedirectContext<CookieAuthenticationOptions> context) { if (context.RedirectUri.StartsWith(ACCOUNT_SITE)) return context; var originUri = new Uri(context.RedirectUri); var uriBuilder = new UriBuilder(ACCOUNT_SITE); uriBuilder.Path = originUri.AbsolutePath; var queryStrings = QueryHelpers.ParseQuery(originUri.Query); var returnUrlName = context.Options.ReturnUrlParameter; var returnUrl = originUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped) + queryStrings[returnUrlName]; uriBuilder.Query = QueryString.Create(returnUrlName, returnUrl).ToString(); context.RedirectUri = uriBuilder.ToString(); return context; }
以上一堆代码用于实现 url 的转换,详见博问 https://q.cnblogs.com/q/108087/
这个长久以来的痛苦总算基于 ASP.NET Core 强大的扩展与配置能力相对优雅地消除了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
- FFRPC应用之Client/Server
- Java8新特性——StreamAPI(二)
- 从WordPress SQLi谈PHP格式化字符串问题
- 自己实现PC端jQuery版轮播图
- Tips for thrift
- Java8新特性——StreamAPI(一)
- springcloud学习手册-Hystrix(仪表盘说明)
- RedRabbit——基于BrokerPattern服务器框架
- C++任务队列与多线程
- 游戏服务器ID生成器组件
- Java8新特性——Lambda表达式(一)
- C++ FFLIB之FFRPC:多线程&多进程的scalability探索
- ffrpc-c++进程间(服务器端、客户端)通信框架
- Docker入门实战(一)——Docker常用命令
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法