设为首页 收藏本站
查看: 1663|回复: 1

[经验分享] ASP.NET Core 2.0使用Cookie认证实现SSO单点登录

[复制链接]

尚未签到

发表于 2017-12-29 10:47:49 | 显示全部楼层 |阅读模式
  之前写了一个使用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文件,用域名去访问
DSC0000.png

  对于每个项目我们都需要在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 href="http://passport.domain.dev/login?returnUrl=http://domain.dev">登录</a>
  
}
  

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

<a 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>
{
[AllowAnonymous]

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

  这样我们就解决了跳转的问题
  好了 ,三个项目的代码都写完了,接下来将这三个项目不熟到IIS里去
DSC0001.png

  这里又得说明一下必须将项目发布以后才能部署到IIS,不能直接指定项目的物理路径,发到文件系统默认的路径应该是bin\Release\PublishOutput,应该指定这个路径
  更新 2017-09-06:上面这句话说的有点绝对,不是一定要发布以后才能部署到IIS,事实上不用发布也可以在IIS中指定项目的根目录,请参考文章《ASP.NET Core开发期间部署到IIS自定义主机域名并附加到进程调试》
DSC0002.png

  建议大家在本地开发的时候尽量合理的使用域名后缀
  代码地址:https://github.com/bidianqing/SSO.Core.Sample

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-429285-1-1.html 上篇帖子: asp.net mvc 自动化测试工具 下篇帖子: 使用批处理脚本愉快的清理缓存
累计签到:184 天
连续签到:6 天
发表于 2017-12-29 11:08:06 | 显示全部楼层
金币不够,回帖来凑

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表