如何解决OWIN中间件无法拦截HttpUnauthorizedResult
我有一个现有项目,我需要使用Open ID Connect实现SSO。我正在使用Okta来测试实现,以后需要使用我们现有的身份验证提供程序。但是,以下是我的情况
- 现有的MVC4项目具有global.asax文件,该文件可处理诸如区域注册,路线注册和全局过滤器注册等常规事务。
- 我已经安装了所需的OWIN软件包并添加了OWIN启动类。
- 运行应用程序时,将触发OWIN启动类,并且配置方法可以正常运行。
- 但是,当用户尝试执行SSO时,OWIN中间件不会拦截
HttpUnauthorizedResult
操作结果,从而导致应用程序返回404错误,而不是重定向到Okta进行登录和同意屏幕。 li>
以下是我看到的错误页面。
- 请查看我在相应文件中拥有的代码
Global.asax
protected void Application_Start(object sender,EventArgs e)
{
//This piece of code is moved to startup.cs to try to resolve this issue but didn't work
//AreaRegistration.RegisterAllAreas();
//WebApiConfig.Register(GlobalConfiguration.Configuration);
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
//RouteConfig.RegisterRoutes(RouteTable.Routes);
//log4net.Config.XmlConfigurator.Configure();
//MvcHandler.DisableMvcResponseHeader = true;
}
protected void Application_BeginRequest(object sender,EventArgs e)
{
CultureInfo newCulture = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
newCulture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
newCulture.DateTimeFormat.DateSeparator = "/";
Thread.CurrentThread.CurrentCulture = newCulture;
Response.AddHeader("X-Frame-Options","DENY");
Response.AddHeader("X-Frame-Options","DENY");
}
- 正如您在上面注意到的那样,我删除了Application_start中的所有内容,并将其移至startup.cs中,但这也没有解决问题。
Startup.cs
private readonly string clientId = ConfigurationManager.AppSettings["okta:ClientId"];
private readonly string redirectUri = ConfigurationManager.AppSettings["okta:RedirectUri"];
private readonly string authority = ConfigurationManager.AppSettings["okta:OrgUri"];
private readonly string clientSecret = ConfigurationManager.AppSettings["okta:ClientSecret"];
private readonly string postLogoutRedirectUri = ConfigurationManager.AppSettings["okta:PostLogoutRedirectUri"];
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,ClientSecret = clientSecret,Authority = authority,RedirectUri = redirectUri,ResponseType = OpenIdConnectResponseType.CodeIdToken,Scope = OpenIdConnectScope.OpenIdProfile,PostLogoutRedirectUri = postLogoutRedirectUri,TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name"
},Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
// Exchange code for access and ID tokens
var tokenClient = new TokenClient(authority + "/v1/token",clientId,clientSecret);
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code,redirectUri);
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
var userInfoClient = new UserInfoClient(authority + "/v1/userinfo");
var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
var claims = new List<Claim>();
claims.AddRange(userInfoResponse.Claims);
claims.Add(new Claim("id_token",tokenResponse.IdentityToken));
claims.Add(new Claim("access_token",tokenResponse.AccessToken));
if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
{
claims.Add(new Claim("refresh_token",tokenResponse.RefreshToken));
}
n.AuthenticationTicket.Identity.AddClaims(claims);
return;
},RedirectToIdentityProvider = n =>
{
// If signing out,add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
var idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenClaim != null)
{
n.ProtocolMessage.IdTokenHint = idTokenClaim.Value;
}
}
return Task.CompletedTask;
}
},});
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
log4net.Config.XmlConfigurator.Configure();
MvcHandler.DisableMvcResponseHeader = true;
}
最后,以下是我的控制器,它将尝试执行SSO。
public ActionResult SingleSignOn()
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.
Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
return new HttpUnauthorizedResult();
}
return RedirectToAction("Index","UserAccess");
}
此外,重要的一点是,我设法在一个只有startup.cs的新项目中使它工作,并通过中间件干预HttpUnauthorizedResult
将我重定向到Okta进行登录。
如果有人能指导我如何成功使OWIN介入HttpUnauthorizedResult
,我将万分感谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。