之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sample,这个Demo是基于.NET Framework,.NET Core 2.0出来了试着使用ASP.NET Core尝试一下。假如我们有三个站点

  • domain.dev
  • order.domain.dev
  • passport.domain.dev

domain.dev作为我们的主站肯定是可以匿名访问的,当点击登录按钮的时候就会跳转到passport.domain.dev,完成登录后跳转回domain.dev。order.domain.dev肯定是不可以匿名访问的必须登录才能访问,所以直接跳转到passport.domain.dev,完成登录后跳转回order.domain.dev。passport作为我们的认证系统,只要登录成功,其他各个系统(例如order,news,)都是登录状态,大概就是实现这么一个功能。

好,打开VisualStudio,哦,对了 VS 2017已经从15.3→15.3.3了,大家可以去升级

先创建三个ASP.NET Core项目,等会我们把这三个项目部署到IIS里去,并修改hosts文件,用域名去访问

对于每个项目我们都需要在Configure和ConfigureServices两个方法中写一些代码,另外Portal和Order不提供登录功能,但是提供注销功能

注册认证中间件就一行代码

app.UseAuthentication();

这里关于认证中间件得说明一下,之前在1.0的时候提供了很多认证的中间件,什么Facebook啊,Google啊,这些中间价将全部弃用,统一使用上面的代码去注册身份认证中间件,具体的认证策略在服务中指定,比如下面的代码AddCookie()方法就指定了使用Cookie认证服务。

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    }).AddCookie(options => {
        options.Cookie.Domain = ".domain.dev";
        options.Cookie.Name = "sso";
        options.Cookie.Path = "/";
        options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"));
    });
    services.AddMvc();
}

需要说明的是DataProtectionProvider属性提供数据保护,会在指定的目录下生成一个xml文件用里面的key去加密cookie。然后在页面上放一个登陆按钮

@if (Context.User.Identity.IsAuthenticated)
{
    @Context.User.Identity.Name <a href="@Url.Action("SignOut")">注销</a>
}
else
{
    <a class="btn btn-default" href="http://passport.domain.dev/login?returnUrl=http://domain.dev">登录</a>
}

OK,Portal项目就完成了。

所有的登陆请求http://passport.domain.dev/login?returnUrl=后面跟上调回的地址,在passport项目的登陆页面放一个登陆按钮(用户名,密码就省了,直接登陆)

<a class="btn btn-default" href="@Url.Action("SignIn","Login",new { returnUrl=Context.Request.Query["returnUrl"]})">登录</a>
public async Task<IActionResult> SignIn(string returnUrl)
{
    var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }, CookieAuthenticationDefaults.AuthenticationScheme));
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTimeOffset.Now.Add(TimeSpan.FromDays(180)),
    });
    if (string.IsNullOrWhiteSpace(returnUrl))
    {
        returnUrl = "http://domain.dev";
    }
    return Redirect(returnUrl);
}

Passport项目的Configure和ConfigureServices方法跟Porta项目保持一样。OK,Passport项目完事了

最后就剩Order项目了,刚才也说了Order项目肯定是不能匿名访问的,这里需要特殊设置一下

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    }).AddCookie(options => {
        options.Cookie.Domain = ".domain.dev";
        options.Cookie.Name = "sso";
        options.Cookie.Path = "/";
        options.LoginPath = "/login";
        options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"));
    });
    // 不允许匿名访问
    services.AddMvc(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
                         .RequireAuthenticatedUser()
                         .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    });
}

说一下LoginPath属性,就是说当用户没有登陆的时候就会跳转到LoginPath,但是LoginPath只能设置本地路径,不能按照下面的方式

options.LoginPath = "http://passport.domain.dev/login";    // 这样是错误的

所以我们上面设置的是/login

public class LoginController : Controller
{
    [AllowAnonymous]
    public IActionResult Index(string returnUrl)
    {
        return Redirect(string.Concat("http://passport.domain.dev/login?returnUrl=http://order.domain.dev", returnUrl));
    }
}

这样我们就解决了跳转的问题

好了 ,三个项目的代码都写完了,接下来将这三个项目不熟到IIS里去

这里又得说明一下必须将项目发布以后才能部署到IIS,不能直接指定项目的物理路径,发到文件系统默认的路径应该是bin\Release\PublishOutput,应该指定这个路径

建议大家在本地开发的时候尽量合理的使用域名后缀

代码地址:https://github.com/bidianqing/SSO.Core.Sample

ASP.NET Core 2.0使用Cookie认证实现SSO单点登录的更多相关文章

  1. NET Core 2.0使用Cookie认证实现SSO单点登录

    NET Core 2.0使用Cookie认证实现SSO单点登录 之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sa ...

  2. .NET Core2.0+MVC 用Redis/Memory+cookie实现的sso单点登录

    之前发布过使用session+cookie实现的单点登录,博主个人用的很不舒服,为什么呢,博主自己测试的时候,通过修改host的方法,在本机发布了三个站点,但是,经过测试,发现,三个站点使用的sess ...

  3. ASP.NET Core 3.0 gRPC 身份认证和授权

    一.开头聊骚 本文算是对于 ASP.NET Core 3.0 gRPC 研究性学习的最后一篇了,以后在实际使用中,可能会发一些经验之文.本文主要讲 ASP.NET Core 本身的认证授权和gRPC接 ...

  4. ASP.NET Core 6.0 添加 JWT 认证和授权

    序言 本文将分别介绍 Authentication(认证) 和 Authorization(授权). 并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能. 相关 ...

  5. .NET Core2.0+MVC 用session,cookie实现的sso单点登录

    博主刚接触.NET Core2.0,想做一个单点登录的demo,所以参考了一些资料,这里给上链接: 1.http://www.cnblogs.com/baibaomen/p/sso-sequence- ...

  6. Asp.net Core 2.0 实现Cookie会话

    与1.0版本相比微软做了一些调整.详细请参考官方文档,我这里就讲2.0的吧 1.首先要在 根目录下 Startup.cs 类中启用 cookie会话,有两处要配置 第一处在  public void ...

  7. ASP.NET Core 2.0 多应用实现Cookie共享

    前言 .NET Core 2.0 发布之后,在Authentication中间件部分,相关API有不少改动(官方文档),本文主要讲的就是实现应用Cookie共享,对Cookie中间件使用不了解的可以去 ...

  8. Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录

    1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...

  9. ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库

    目录 说明 一.定义角色.API.用户 二.添加自定义事件 三.注入授权服务和中间件 三.如何设置API的授权 四.添加登录颁发 Token 五.部分说明 六.验证 说明 ASP.NET Core 3 ...

随机推荐

  1. [luogu P3787][新创无际夏日公开赛] 冰精冻西瓜 [树状数组][dfs序]

    题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...

  2. [vijos 1642]班长的任务 [树形dp]

    背景 十八居士的毕业典礼(1) 描述 福州时代中学2009届十班同学毕业了,于是班长PRT开始筹办毕业晚会,但是由于条件有限,可能每个同学不能都去,但每个人都有一个权值,PRT希望来的同学们的权值总和 ...

  3. (转)mysql水平分表和垂直分表和数据库分区

    坚信数据库的物理设计在对高级数据库的性能影响上远比其他因素重要.给大家说一下经过专家对Oracle的研究,他们解释了为什么拙劣的物理设计是数据库停机(无论是有计划的还是没计划的)背后的主要原因.但在这 ...

  4. swift3.0 coreData的使用-日记本demo

    效果 需求分析 基于官方MasterDetail模板,官方写了很多复杂的coredata逻辑,在此基础上快速开发简单的日记本程序. - 主要功能:增.删.改.查 - 界面用默认的界面,将detail页 ...

  5. Docker存储

    前言 上一篇文章中简单总结了一下docke的基础使用方法,这次我来总结一下有关docker存储方面的相关知识.本文同样建立在CloudMan的系列教程之上,有兴趣的可以直接移步. 有些人可能觉得这个很 ...

  6. ctf中常见注入题源码及脚本分析

    1.代码审计发现 这里没有用escape_string,因此存在注入. function show($username){ global $conn; $sql = "select role ...

  7. theOS环境搭建

    http://joeyio.com/ios/2014/01/01/make-a-mobile-substrate-tweak-using-theos/~/Doucment>: cd mytwea ...

  8. macOS下加载动态库dylib报"code signature invalid"错误的解决办法

    一.现象描述 在macOS上搞开发也有一段时间了,也积攒了一定的经验.然而,今天在替换工程中的一个动态库时还是碰到了一个问题.原来工程中用的是一个静态库,调试时发现有问题就把它替换成了动态库.这本来没 ...

  9. ECC椭圆曲线详解(有具体实例)

    前言 ECC英文全称"Ellipse Curve Cryptography" 与传统的基于大质数因子分解困难性的加密方法不同,ECC通过椭圆曲线方程式的性质产生密钥 ECC164位 ...

  10. vue中使用cropperjs进行图片裁剪上传

    下面代码直接就可以复制使用了,但是需要在本地下个cropperjs,下载命令:npm install cropperjs --save-dev <template> <div id= ...