双OWIN身份验证不能一起工作

对于我的网站,我正在使用OWIN OpenId与第三方身份验证提供程序进行集成,以允许访问者注册/登录/注销。 “Second”双OWIN身份验证不能一起工作

对于我的应用程序,我还有一个测试环境,在将这些更改推送到生产之前,测试所有代码更改。我将测试环境与另一个第三方身份验证提供程序的公共访问隔开,并使用OWIN OpenId以及“First”。只有经过验证的访问者才能访问测试环境网站。

现在的问题是,这两个工作是独立的,但我似乎无法将它们结合起来。我试图实现的是,我可以通过使用First进行身份验证来访问测试环境,然后作为regluar访问者使用Second进行身份验证,以查看为注册访问者设计的内容。

下面是我在做什么:

两个authnetication提供商与cookie认证工作,但我给了他们一个不同的AuthenticationType把它们分开。

if (IsEnabled("First")) 

app.SetDefaultSignInAsAuthenticationType("First");

else

app.SetDefaultSignInAsAuthenticationType("Second");

// Configure First.

if (IsEnabled("First")) {

app.UseCookieAuthentication(First.CookieAuthenticationOptions); // AuthenticationType is set to "First" in these options.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions

{

ClientId = First.AADClientId,

Authority = First.Authority,

Notifications = new OpenIdConnectAuthenticationNotifications

{

AuthenticationFailed = context => { ... },

RedirectToIdentityProvider = context => { ... }

},

AuthenticationType = "First"

});

app.Map($"{First.Path}/login", config =>

{

config.Run(context =>

{

context.Authentication.Challenge(new AuthenticationProperties

{ RedirectUri = First.ReturnUrl, IsPersistent = true },

"First"

);

context.Response.StatusCode = 401;

return context.Response.WriteAsync(string.Empty);

});

});

}

// Configure Second.

app.UseCookieAuthentication(Second.CookieAuthenticationOptions); // AuthenticationType is set to "Second" in these options.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions

{

UseTokenLifetime = false,

Notifications = new OpenIdConnectAuthenticationNotifications

{

AuthenticationFailed = x => ...,

RedirectToIdentityProvider = x =>

{

var mgr = x.Options.ConfigurationManager as PolicyConfigurationManager;

if (x.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)

{

var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,

x.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary["PolicyId"]);

x.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;

}

else

{

var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,

x.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["PolicyId"]);

x.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;

}

var redirectUri = Second.ReturnPath;

x.ProtocolMessage.RedirectUri = redirectUri;

x.ProtocolMessage.PostLogoutRedirectUri = redirectUri;

},

SecurityTokenValidated = x => ...

},

Scope = "openid",

ResponseType = "id_token",

ReturnUri = Second.ReturnUri,

ClientId = Second.ClientId,

ConfigurationManager = GetConfigurationManager()

AuthenticationType = configuration.AuthenticationType

});

app.Map(Second.LoginPath, config =>

{

// Trigger unauthorized so that active authentication will redirect to active directory.

config.Run(context =>

{

// Set policy in context to mitigate null ref exception in Startup.Auth OnRedirectToIdentityProvider

context.Authentication.Challenge(

new AuthenticationProperties(new Dictionary<string, string>

{

{"PolicyId", Second.LoginPolicyId}

})

{

IsPersistent = true,

RedirectUri = returnUrl

}, "Second");

context.Response.StatusCode = 401;

// Middleware will redirect us instead of using this output.

return context.Response.WriteAsync(string.Empty);

});

});

app.Map(Second.ReturnPath, config =>

{

config.Use((context, next) =>

{

// In case of login, we will never get here because we will get redirected by middleware.

context.Response.Redirect("/");

return Task.FromResult(0);

});

});

当第一次启用,这允许我做

var identity = HttpContext.Current.GetOwinContext.Authentication.AuthenticateAsync("Second").Result?.Identity; 

在后续请求中,有一个ClaimsIdentity。但是,当First启用时,出于某种原因,上述结果为空。

我注意到,当我启用第一和第二,并将DefaultSignInAsAuthenticationType设置为“第二”,它是第一个不再工作。如果我同时启用First和Second,并使用First的先前身份验证Cookie浏览网站,则一切正常。

我猜测返回方法,某处设置身份验证cookie需要一些AuthenticationType的引用,但我不知道该在哪里做。

我缺少什么?

回答:

诀窍是第二配置时AuthenticationType添加到TokenValidationParameters,像这样:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions 

{

UseTokenLifetime = false,

Notifications = new OpenIdConnectAuthenticationNotifications

{

AuthenticationFailed = x => ...,

RedirectToIdentityProvider = x =>

{

var mgr = x.Options.ConfigurationManager as PolicyConfigurationManager;

if (x.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)

{

var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,

x.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary["PolicyId"]);

x.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;

}

else

{

var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,

x.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["PolicyId"]);

x.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;

}

var redirectUri = Second.ReturnPath;

x.ProtocolMessage.RedirectUri = redirectUri;

x.ProtocolMessage.PostLogoutRedirectUri = redirectUri;

},

SecurityTokenValidated = x => ...

},

Scope = "openid",

ResponseType = "id_token",

ReturnUri = Second.ReturnUri,

ClientId = Second.ClientId,

ConfigurationManager = GetConfigurationManager(),

AuthenticationType = configuration.AuthenticationType,

// ADD THIS TO MAKE IT WORK:

TokenValidationParameters = new TokenValidationParameters

{

AuthenticationType = configuration.AuthenticationType

}

});

以上是 双OWIN身份验证不能一起工作 的全部内容, 来源链接: utcz.com/qa/267098.html

回到顶部