- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解ASP.NET Core和ASP.NET Framework共享身份验证由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
.NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源、组件化、跨平台、性能优秀、社区活跃等等标签再加上“微软爸爸”主推和大力支持,尽管现阶段对比.net framework还是比较“稚嫩”,但可以想象到它光明的前景。作为.net 开发者你是否已经开始尝试将项目迁移到.net core上?这其中要解决的一个较大的问题就是如何让你的.net core和老.net framework站点实现身份验证兼容! 。
1、第一篇章 。
我们先来看看.net core中对identity的实现,在Startup.cs的Configure中配置Cookie认证的相关属性 。
1
2
3
4
5
6
7
8
|
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCookieAuthentication(
new
CookieAuthenticationOptions
{
AuthenticationScheme =
"test"
,
CookieName =
"MyCookie"
});
}
|
Controller 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public
IActionResult Index()
{
return
View();
}
public
IActionResult Login()
{
return
View();
}
[HttpPost]
public
async Task<IActionResult> Login(
string
name)
{
var identity =
new
ClaimsIdentity(
new
List<Claim>
{
new
Claim(ClaimTypes.Name,name, ClaimValueTypes.String)
},
ClaimTypes.Authentication,
ClaimTypes.Name,
ClaimTypes.Role);
var principal =
new
ClaimsPrincipal(identity);
var properties =
new
AuthenticationProperties { IsPersistent =
true
};
await HttpContext.Authentication.SignInAsync(
"test"
, principal, properties);
return
RedirectToAction(
"Index"
);
}
|
login 视图 。
1
2
3
4
5
6
7
8
9
10
11
|
<!DOCTYPE html>
<
html
>
<
head
>
<
title
>登录</
title
>
</
head
>
<
body
>
<
form
asp-controller
=
"Account"
asp-action
=
"Login"
method
=
"post"
>
<
input
type
=
"text"
name
=
"name"
/><
input
type
=
"submit"
value
=
"提交"
/>
</
form
>
</
body
>
</
html
>
|
index 视图 。
1
2
3
4
5
6
7
8
9
10
11
12
|
<!DOCTYPE html>
<
html
>
<
head
>
<
title
>欢迎您-@User.Identity.Name</
title
>
</
head
>
<
body
>
@if (User.Identity.IsAuthenticated)
{
<
p
>登录成功!</
p
>
}
</
body
>
</
html
>
|
下面是实现效果的截图:
ok,到此我们用.net core比较简单地实现了用户身份验证信息的保存和读取.
接着思考,如果我的.net framework项目想读取.net core项目保存的身份验证信息应该怎么做?
要让两个项目都接受同一个Identity至少需要三个条件:
首先我们对.net core的Cookie认证添加domain属性和ticket属性 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var protectionProvider = DataProtectionProvider.Create(
new
DirectoryInfo(@"C:\keyPath\"));
var dataProtector = protectionProvider.CreateProtector(
"MyCookieAuthentication"
);
var ticketFormat =
new
TicketDataFormat(dataProtector);
app.UseCookieAuthentication(
new
CookieAuthenticationOptions
{
AuthenticationScheme =
"test"
,
CookieName =
"MyCookie"
,
CookieDomain =
"localhost"
,
TicketDataFormat = ticketFormat
});
}
|
此时我们在.net core 项目中执行用户登录,程序会在我们指定的目录下生成key.xml 。
我们打开文件看看程序帮我们记录了那些信息 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
key
id
=
"eb8b1b59-dbc5-4a28-97ad-2117a2e8f106"
version
=
"1"
>
<
creationDate
>2016-12-04T08:27:27.8435415Z</
creationDate
>
<
activationDate
>2016-12-04T08:27:27.8214603Z</
activationDate
>
<
expirationDate
>2017-03-04T08:27:27.8214603Z</
expirationDate
>
<
descriptor
deserializerType
=
"Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
>
<
descriptor
>
<
encryption
algorithm
=
"AES_256_CBC"
/>
<
validation
algorithm
=
"HMACSHA256"
/>
<
masterKey
p4:requiresEncryption
=
"true"
xmlns:p4
=
"http://schemas.asp.net/2015/03/dataProtection"
>
<
value
>yHdMEYlEBzcwpx0bRZVIbcGJ45/GqRwFjMfq8PJ+k7ZWsNMic0EMBgP33FOq9MFKX0XE/a1plhDizbb92ErQYw==</
value
>
</
masterKey
>
</
descriptor
>
</
descriptor
>
</
key
>
|
ok,接下来我们开始配置.net framework项目,同样,在Startup.cs中配置Cookie认证的相关属性.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
partial
class
Startup
{
public
void
Configuration(IAppBuilder app)
{
var protectionProvider = DataProtectionProvider.Create(
new
DirectoryInfo(
@"C:\keyPath\"
));
var dataProtector = protectionProvider.CreateProtector(
"MyCookieAuthentication"
);
var ticketFormat =
new
AspNetTicketDataFormat(
new
DataProtectorShim(dataProtector));
app.UseCookieAuthentication(
new
CookieAuthenticationOptions
{
AuthenticationType =
"test"
,
CookieName =
"MyCookie"
,
CookieDomain =
"localhost"
,
TicketDataFormat = ticketFormat
});
}
}
|
view 。
1
2
3
4
5
6
7
8
9
10
11
12
|
<!DOCTYPE html>
<
html
>
<
head
>
<
title
>.net framewor欢迎您-@User.Identity.Name</
title
>
</
head
>
<
body
>
@if (User.Identity.IsAuthenticated)
{
<
p
>.net framework登录成功!</
p
>
}
</
body
>
</
html
>
|
写法和.net core 基本上是一致的,我们来看下能否成功获取用户名:
反之在.net framework中登录在.net core中获取身份验证信息的方法是一样的,这里就不重复写了.
然而,到此为止事情就圆满解决了吗?很遗憾,麻烦才刚刚开始! 。
-------------------------------------------------------------------------------- 。
2、第二篇章 。
如果你的子项目不多,也不复杂的情况下,新增一个.net core 站点,然后适当修改以前的.net framework站点,上述实例确实能够满足需求。可是如果你的子站点足够多,或者项目太过复杂,牵扯到的业务过于庞大或重要,这种情况下我们通常是不愿意动老项目的。或者说我们没有办法将所有的项目都进行更改,然后和新增的.net core站点同时上线,如果这么做了,那么更新周期会拉的很长不说,测试和更新之后的维护阶段压力都会很大。所以我们必须要寻找到一种方案,让.net core的身份验证机制完全迎合.net framwork.
因为.net framework 的cookie是对称加密,而.net core是非对称加密,所以要在.net core中动手的话必须要对.net core 默认的加密和解密操作进行拦截,如果可行的话最好的方案应该是将.net framework的FormsAuthentication类移植到.net core中。但是用reflector看了下,牵扯到的代码太多,剪不断理还乱,github上也没找到其源码,瞎忙活了一阵之后终于感慨:臣妾做不到(>﹏< ).
Cookie认证的相关属性 。
1
2
3
4
5
6
7
|
app.UseCookieAuthentication(
new
CookieAuthenticationOptions
{
AuthenticationScheme =
"test"
,
CookieName =
"MyCookie"
,
CookieDomain =
"localhost"
,
TicketDataFormat =
new
FormsAuthTicketDataFormat(
""
)
});
|
FormsAuthTicketDataFormat 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public
class
FormsAuthTicketDataFormat : ISecureDataFormat<AuthenticationTicket>
{
private
string
_authenticationScheme;
public
FormsAuthTicketDataFormat(
string
authenticationScheme)
{
_authenticationScheme = authenticationScheme;
}
public
AuthenticationTicket Unprotect(
string
protectedText,
string
purpose)
{
var formsAuthTicket = GetFormsAuthTicket(protectedText);
var name = formsAuthTicket.Name;
DateTime issueDate = formsAuthTicket.IssueDate;
DateTime expiration = formsAuthTicket.Expiration;
var claimsIdentity =
new
ClaimsIdentity(
new
Claim[] {
new
Claim(ClaimTypes.Name, name) },
"Basic"
);
var claimsPrincipal =
new
ClaimsPrincipal(claimsIdentity);
var authProperties =
new
Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties
{
IssuedUtc = issueDate,
ExpiresUtc = expiration
};
var ticket =
new
AuthenticationTicket(claimsPrincipal, authProperties, _authenticationScheme);
return
ticket;
}
FormsAuthTicket GetFormsAuthTicket(
string
cookie)
{
return
DecryptCookie(cookie).Result;
}
async Task<FormsAuthTicket> DecryptCookie(
string
cookie)
{
HttpClient _httpClient =
new
HttpClient();
var response = await _httpClient.GetAsync(
"http://192.168.190.134/user/getMyTicket?cookie={cookie}"
);
response.EnsureSuccessStatusCode();
return
await response.Content.ReadAsAsync<FormsAuthTicket>();
}
}
|
FormsAuthTicket 。
1
2
3
4
5
6
|
public
class
FormsAuthTicket
{
public
DateTime Expiration {
get
;
set
; }
public
DateTime IssueDate {
get
;
set
; }
public
string
Name {
get
;
set
; }
}
|
以上实现了对cookie的解密拦截,然后通过webapi从.net framework获取ticket 。
1
2
3
4
5
6
|
[Route(
"getMyTicket"
)]
public
IHttpActionResult GetMyTicket(
string
cookie)
{
var formsAuthTicket = FormsAuthentication.Decrypt(cookie);
return
Ok(
new
{ formsAuthTicket.Name, formsAuthTicket.IssueDate, formsAuthTicket.Expiration });
}
|
有了webapi这条线,解密解决了,加密就更简单了,通过webapi获取加密后的cookie,.net core要做的只有一步,保存cookie就行了 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[HttpPost]
public
async Task<IActionResult> Login(
string
name)
{
HttpClient _httpClient =
new
HttpClient();
var response = await _httpClient.GetAsync($
"http://192.168.190.134/user/getMyCookie?name={name}"
);
response.EnsureSuccessStatusCode();
string
cookieValue = (await response.Content.ReadAsStringAsync()).Trim(
'\"'
);
CookieOptions options =
new
CookieOptions();
options.Expires = DateTime.MaxValue;
HttpContext.Response.Cookies.Append(
"MyCookie"
, cookieValue, options);
return
RedirectToAction(
"Index"
);
}
|
webapi获取cookie 。
1
2
3
4
5
6
|
[Route(
"getMyCookie"
)]
public
string
GetMyCookie(
string
name)
{
FormsAuthentication.SetAuthCookie(name,
false
);
return
FormsAuthentication.GetAuthCookie(name,
false
).Value;
}
|
其余代码不用做任何更改,ok,我们来测试一下 。
ok,登录成功,至此完成.net framework和.net core身份验证的兼容,哎,如果.net core 的团队能多考虑一些这方面的兼容问题,哪怕是一个折中方案也能让开发者更有动力去做迁移.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/Jermey/p/6130324.html 。
最后此篇关于详解ASP.NET Core和ASP.NET Framework共享身份验证的文章就讲到这里了,如果你想了解更多关于详解ASP.NET Core和ASP.NET Framework共享身份验证的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
只是想知道是否有可能找出谁从 Windows 共享中读取了文件(最好使用 .NET,但 win32 native 可以)? 我想做的是创建类似 awstats 的东西对于 Windows 共享,这样我
是否可以列出 Intent.ACTION_SEND ?我的意思是我需要知道是否有人通过 action_send 在 Facebook 上分享或在 Twitter 上发推文。 最佳答案 也许你想要一个更
我正在使用 Google Apps 应用程序。实际上,我想在不使用密码的情况下访问另一个 ID。我使用了 OAuth,它运行良好。但我无法分享特定人的日历。我尝试了以下代码。 GoogleOAuthP
我怎样才能只创建模拟器...可能吗?我知道,设备需要分发证书。 最佳答案 您只需将应用程序目录从 iPhone 模拟器复制到另一个实例/操作系统版本,它就应该可以工作。 因此,如果您想分发 3.1.3
我想使用多阶段构建来避免每次构建应用程序时都下载我的 Java 项目所需的所有 Maven 依赖项。 我正在考虑在第一阶段解决 Maven 依赖项,然后在第二阶段构建应用程序,这将需要访问在前一阶段下
我正在寻找保护用户下载内容的初步想法。用户下载充满有趣资源的 zip 文件,这些资源被提取到本地文件系统中以供应用程序使用。我的目标是防止用户通过互联网将下载的资源共享给其他用户(假设他们获得了对文件
我想知道在具有移动和桌面版本的网站上共享身份验证、 session 管理等的最佳方法是什么。我们正在运行 Tomcat,并且更愿意将移动站点和桌面站点的应用程序保持在不同的节点上。 我看过类似的帖子,
我发现了这个单例的实现。我怎样才能创建指向它的指针或共享指针?` 为什么这不起作用?自动测试 = Singleton::Instance(); class Singleton { public: st
我有一个 heroku 项目,我想与其他人分享。作为the instructions describe ,我使用 virtualenv 来管理环境和依赖项。有没有办法在新机器上从 requiremen
Maven 将所有 jar 存储在本地存储库 ~/.m2/repository/ 下。用户多时占用空间大。 那么,是否可以由多个用户共享这个本地存储库,或许在不同的目录结构下? 最佳答案 简单的回答
为什么共享 worker 在重新加载页面时死了?应该是复活了我该如何解决这个问题? 重装前 重新加载后(在example.com上按F5) parent worker var port = new S
我正在开发多个小型应用程序,这些应用程序将共享通用和共享模块和 Assets 。 关于如何创建项目结构的部分在这里回答:https://stackoverflow.com/a/61254557/135
我在 RHEL 上安装了 jenkins (localhost:8080),我能够成功地构建代码 现在,我想设置主/从代理。 我的笔记本电脑将充当“Master Jenkins”,而我同事的笔记本电脑
我有这种方法可以根据我使用的 EXTRA_STREAM 共享文本文件或图片。我有这两个我可以选择 i.putExtra(Intent.EXTRA_STREAM, uri); i.putExtra(In
我正在使用 R 中的一个数据分析项目,我正在使用 R 中的敏感私有(private)数据进行一些逻辑和多级建模。我爱上了 。预订 包,我已经创建了一本关于我们的工作流程和分析管道的相当广泛的书。问题是
我正在构建的应用程序需要在 UITabBarController 框架内为多个 View (及其 subview )显示共享的自定义 UIToolbar。自定义工具栏的内容在所有 View 中都是相同
我有多个应用程序,我想共享相同的 eslint 配置: - project_root/ - app1/ - node_modules/ - eslint.rc
我有多个 Electron 应用程序。一个是主应用程序,其他几个功能应用程序。主应用程序上的按钮很少,这将导致功能应用程序打开。这里的问题是每个应用程序都有一个主进程,该进程导致要利用更多的CPU。是
我正在开发一个 Node.js 后端,它通过 websocket 与一些桌面客户端进行通信,而服务器端的通信是从 Web 前端发起的。一切正常,因为我将 SockJS Connection 实例存储在
我对托管多个网站的服务器上的多个用户帐户使用私有(private) SSH key 和无密码条目。 我为每个用户帐户使用相同的私钥。 (因为我很懒?或者那是“正确”的方式)。 我现在想授权该国不同地区
我是一名优秀的程序员,十分优秀!