2016-04-08 74 views
1

我一直被委托将IDS3集成到现有遗留的MVC应用程序中,该应用程序已迁移到使用CookieAuthentication的OWIN。通过很棒的示例项目,我设法使用自定义用户服务,自定义登录页面和代码流测试客户端进行简单设置。在自定义登录页面上使用现有Cookie身份验证状态

我现在试图解决这个问题:如果用户已经通过现有的cookie身份验证登录并通过我们的测试客户端启动代码流,则会自动将它们登录到IDS3,以免它们提示输入他们的再次验证。这里是不工作的代码,以显示我的思维过程:

[Route("identity/logintest", Name = "ids3-login")] 
public ActionResult IdsLogin(string id) 
{ 
    var ctx = Request.GetOwinContext(); 
    var user = ctx.Authentication.User; 

    // If they're already logged in via cookie auth, automatically 
    // log them in to IDS3 and send them on their way 
    if (user.Identity.IsAuthenticated) 
    { 
     var env = ctx.Environment; 

     env.IssueLoginCookie(new IdentityServer3.Core.Models.AuthenticatedLogin 
     { 
      Subject = User.Identity.Name, 
      Name = User.Identity.Name, 
     }); 

     var msg = env.GetSignInMessage(id); 
     var returnUrl = msg.ReturnUrl; 

     env.RemovePartialLoginCookie(); 

     return Redirect(returnUrl); 
    } 

    // Otherwise show the login form as usual 
    return View(); 
} 

如果我登录为通过cookie认证用户,user.Identity的值不填充了信息,因此IsAuthenticated是假的。我想我有一个伪理解为什么目前失败:我要求与IDS3关联的上下文的Authentication值,而不是我的MVC应用程序具有cookie身份验证后的身份验证值。 (这是概念混乱,因为该控制器是我的MVC应用程序的一部分。)

这可能是更少的IDS3问题和更大的OWIN问题的,但我的希望是,有人试图实现这个哈克之前的做法,可以指引我正确的方向。希望当我通过所有在http://www.asp.net/aspnet/samples/owin-katana上发现的OWIN样本时,事情会变得更有意义,但现在我被卡住了。

Startup.cs供参考(不包括自定义用户的服务代码,它基本上是从CustomLoginPage示例项目复制粘贴):

public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var container = AutofacConfig.Configure(); 

     app.UseAutofacMiddleware(container); 
     app.UseAutofacMvc(); 

     ConfigureAuthentication(app); 
     ConfigureIdentityServer(app); 
    } 

    private static void ConfigureAuthentication(IAppBuilder app) 
    { 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, 
      LoginPath = new PathString("/login") 
     }); 
    } 

    private static void ConfigureIdentityServer(IAppBuilder app) 
    { 
     var factory = new IdentityServerServiceFactory() 
      .UseInMemoryClients(Clients.Get()) 
      .UseInMemoryScopes(StandardScopes.All); 

     factory.UserService = new Registration<IUserService>(resolver => 
      resolver.ResolveFromAutofacOwinLifetimeScope<IUserService>()); 

     var options = new IdentityServerOptions 
     { 
      SiteName = "test", 
      SigningCertificate = LoadCertificate(), 
      Factory = factory, 

      AuthenticationOptions = new AuthenticationOptions 
      { 
       EnableLocalLogin = true, 

      } 
     } 

     app.Map("/identity", idsrvApp => 
     { 
      idsrvApp.UseIdentityServer(options); 
     }); 
    } 
} 

回答

0

如果用户已经通过现有的Cookie登录认证并开始通过我们的测试客户端的代码流,自动登录他们以IDS3,这样不会提示他们如果要实现自定义的用户服务PreAuthenticate那么y再次输入其凭据

您可以检测您的自定义Cookie以了解用户已经通过身份验证。然后您可以从PreAuthenticate发出有效的AuthenticationResult。我们有一个样本显示这样的事情。

我不确定上面的代码的其余部分 - 我对你为什么拥有它以及它适合什么地方有些困惑,所以我很犹豫为什么它可能或不可以评论正在工作。

+0

试图实施PreAuthenticate实际上是我第一次尝试,但我无法弄清楚检测自定义cookie位。我的第一个尝试是通过注入IOwinEnvironment来识别用户,从中创建OwinContext,然后检查Authentication.User.Identity.IsAuthenticated的状态,即使我已经登录到自定义cookie身份验证,该状态始终为false。尝试#2是尝试从请求中提取我的身份验证cookie,将其解密,然后从那里检查身份验证。这是你通过检测自定义cookie建议的,还是有另一个选项,我错过了? – timbermeshivers

+0

那么,你说它是在一个自定义的cookie中 - 如果你有owin上下文,那么你应该能够到达cookie。访问User.IsAuthenticated可能不是正确的事情 - 但您应该能够调用AuthenticateAsync来获取katana代码来检查cookie。 –

+0

成功!感谢您的帮助。我能够检索cookie和其中的声明标识。我显然使用了一些过时的技术来尝试解密cookie,但是当我重新访问代码时,几天没有注意它就跳出来了。 – timbermeshivers

0

很高兴看到有人需要与我一样的hacky解决方案。我必须使用旧的Membership cookie来使用IdentityServer对用户进行身份验证。我的解决方案非常简单 - 我没有使用user.Identity.IsAuthenticated,但是直接从Response中读取cookie值作为Raw值,并使用Membership类从中解密用户名。通过这个,我没有遇到不同的Cookie提供者进行身份验证的麻烦。由于整个概念无论如何都不好意思,我不介意在这种情况下手动读取cookie。