mvc自定义oauth服务器不会在未经授权的情况下重定向到登录页面
本文关键字:重定向 情况下 登录 授权 服务器 oauth 自定义 mvc | 更新日期: 2023-09-27 18:21:37
我设置了自己的oauth授权服务器(NO通过Facebook、Google和co登录)。不幸的是,在达到授权端点后,我的服务器不会重定向到登录页面。为什么中间件不重定向到我的登录页面?
我遵循了一些教程:
- OWIN OAuth 2.0授权服务器
- OAuth自定义提供程序c#(顺便说一句,这是我找到的唯一一个客户端登录到自定义OAuth服务器的代码示例。感谢@MatthiasRamp。我读到的所有其他内容都是关于如何使用社交媒体客户端登录的,这非常令人沮丧)
- MVC 5应用程序-实现OAuth授权代码流
这就是我在oauth服务器端做的短端:
Startup.Auth.cs
使用登录路径的活动Cookie身份验证Startup.Auth.cs
使用被动Cookie身份验证Startup.Auth.cs
使用AuthorizeEndpointPath的授权服务器SecurityController/Authorize
调用Authentication.challenge()
将状态更改为401
他在@Satish p的帖子中描述了一点:
- 将客户端重定向到登录页面
为此,我设置属性CookieAuthenticationOptions.LoginPath
,它告诉我
LoginPath属性通知中间件,它应该将传出的401未经授权的状态代码更改为302重定向到给定的登录路径上。
这是我的Startup.Auth.cs
,包括LoginPath
:
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Application",
AuthenticationMode = AuthenticationMode.Passive,
LoginPath = new PathString("/Security/Login"),
LogoutPath = new PathString("/Security/Logout")
});
// Enable the External Sign In Cookie.
app.SetDefaultSignInAsAuthenticationType("External");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "External",
AuthenticationMode = AuthenticationMode.Passive,
CookieName = CookieAuthenticationDefaults.CookiePrefix + "External",
ExpireTimeSpan = TimeSpan.FromMinutes(5),
});
// The UseOAuthAuthorizationServer extension method is to setup the authorization server. The setup options are: [...]
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AuthorizeEndpointPath = new PathString("/Security/Authorize"),
TokenEndpointPath = new PathString("/Token"),
ApplicationCanDisplayErrors = true,
#if DEBUG
AllowInsecureHttp = true,
#endif
// Authorization server provider which controls the lifecycle of Authorization Server
Provider = new ApplicationOAuthProvider(PublicClientId)
});
}
我创建了一个派生自OAuthAuthorizationServerProvider
的类。
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// [Check username and pw here]
var oAuthIdentity = new ClaimsIdentity(new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
var cookiesIdentity = new ClaimsIdentity(new GenericIdentity(context.UserName, CookieAuthenticationDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
AuthenticationProperties properties = CreateProperties(context.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
var grantType = context.Parameters.SingleOrDefault(p => p.Key == "grant_type").Value;
if (grantType != null)
{
if (grantType[0] == "authorization_code")
{
string clientId;
string clientSecret;
if (context.TryGetBasicCredentials(out clientId, out clientSecret) || context.TryGetFormCredentials(out clientId, out clientSecret))
{
if (clientId == Clients.ClientApp.Id && clientSecret == Clients.ClientApp.Secret)
{
context.Validated();
}
}
}
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == Clients.ClientApp.Id)
{
context.Validated(Clients.ClientApp.RedirectUrl);
}
return Task.FromResult<object>(null);
}
public static AuthenticationProperties CreateProperties(string userName)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName }
};
return new AuthenticationProperties(data);
}
}
这就是重定向应该发生的地方,因为质询会将响应更改为未授权(401)。它希望返回authorize视图,而不是重定向到登录页面。
public ActionResult Authorize()
{
if (Response.StatusCode != 200)
{
return View("AuthorizeError");
}
var authType = DefaultAuthenticationTypes.ApplicationCookie;
var authentication = HttpContext.GetOwinContext().Authentication;
var ticket = authentication.AuthenticateAsync(authType).Result;
var identity = ticket != null ? ticket.Identity : null;
if (identity == null)
{
authentication.Challenge(authType);
}
else
{
// login stuff
}
return View();
}
我知道已经太晚了,你可能不再需要这个了,但以防万一,如果其他人也面临这个问题,那么你需要返回HttpUnauthorizedResult();挑战后,它会重新提示您登录页面。例如
if (identity == null)
{
authentication.Challenge(authType);
return new HttpUnauthorizedResult();
}
//login stuff