gpt4 book ai didi

c# - OWIN OpenID 连接授权无法授权安全 Controller /操作

转载 作者:太空狗 更新时间:2023-10-29 17:57:01 25 4
gpt4 key购买 nike

我正在开展一个项目,其中第三方提供商将充当基于 Oauth2 的授权服务器。基于 Asp.net MVC 5 的客户端,它将用户发送到授权服务器进行身份验证(使用登录名/密码),授权服务器将访问 token 返回给 MVC 客户端。将使用访问 token 对资源服务器 (API) 进行任何进一步调用。

为此,我使用了 Microsoft.Owin.Security.OpenIdConnect 和 UseOpenIdConnectAuthentication 扩展。我能够成功重定向并从身份验证服务器获取访问 token ,但客户端未创建身份验证 Cookie。每次我尝试访问安全页面时,我都会得到带有访问 token 的回调页面。

我在这里错过了什么?我当前的代码如下。

安全 Controller 操作:

namespace MvcWebApp.Controllers
{
public class SecuredController : Controller
{
// GET: Secured
[Authorize]
public ActionResult Index()
{
return View((User as ClaimsPrincipal).Claims);
}
}
}

启动类:

public class Startup
{
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType("ClientCookie");

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = "ClientCookie",
CookieName = CookieAuthenticationDefaults.CookiePrefix + "ClientCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(5)
});

// ***************************************************************************
// Approach 1 : ResponseType = "id_token token"
// ***************************************************************************
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
Authority = "https://thirdparty.com.au/oauth2",
ClientId = "_Th4GVMa0JSrJ8RKcZrzbcexk5ca",
ClientSecret = "a3GVJJbLHkrn9nJRj3IGNvk5eGQa",
RedirectUri = "http://mvcwebapp.local/",
ResponseType = "id_token token",
Scope = "openid",

Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://thirdparty.com.au/oauth2/authorize",
TokenEndpoint = "https://thirdparty.com.au/oauth2/token",
UserInfoEndpoint = "https://thirdparty.com.au/oauth2/userinfo",
},

Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
var token = n.ProtocolMessage.AccessToken;

// persist access token in cookie
if (!string.IsNullOrEmpty(token))
{
n.AuthenticationTicket.Identity.AddClaim(
new Claim("access_token", token));
}

return Task.FromResult(0);
},

AuthenticationFailed = notification =>
{
if (string.Equals(notification.ProtocolMessage.Error, "access_denied", StringComparison.Ordinal))
{
notification.HandleResponse();

notification.Response.Redirect("/");
}

return Task.FromResult<object>(null);
}
}
});

// ***************************************************************************
// Approach 2 : ResponseType = "code"
// ***************************************************************************
//app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
//{
// AuthenticationMode = AuthenticationMode.Active,
// AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
// SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
// Authority = "https://thirdparty.com.au/oauth2",
// ClientId = "_Th4GVMa0JSrJ8RKcZrzbcexk5ca",
// ClientSecret = "a3GVJJbLHkrn9nJRj3IGNvk5eGQa",
// RedirectUri = "http://mvcwebapp.local/",
// ResponseType = "code",
// Scope = "openid",

// Configuration = new OpenIdConnectConfiguration
// {
// AuthorizationEndpoint = "https://thirdparty.com.au/oauth2/authorize",
// TokenEndpoint = "https://thirdparty.com.au/oauth2/token",
// UserInfoEndpoint = "https://thirdparty.com.au/oauth2/userinfo",
// },

// Notifications = new OpenIdConnectAuthenticationNotifications
// {
// AuthorizationCodeReceived = async (notification) =>
// {
// using (var client = new HttpClient())
// {
// var configuration = await notification.Options.ConfigurationManager.GetConfigurationAsync(notification.Request.CallCancelled);
// var request = new HttpRequestMessage(HttpMethod.Get, configuration.TokenEndpoint);
// request.Content = new FormUrlEncodedContent(new Dictionary<string, string>
// {
// {OpenIdConnectParameterNames.ClientId, notification.Options.ClientId},
// {OpenIdConnectParameterNames.ClientSecret, notification.Options.ClientSecret},
// {OpenIdConnectParameterNames.Code, notification.ProtocolMessage.Code},
// {OpenIdConnectParameterNames.GrantType, "authorization_code"},
// {OpenIdConnectParameterNames.ResponseType, "token"},
// {OpenIdConnectParameterNames.RedirectUri, notification.Options.RedirectUri}
// });

// var response = await client.SendAsync(request, notification.Request.CallCancelled);
// response.EnsureSuccessStatusCode();

// var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

// // Add the access token to the returned ClaimsIdentity to make it easier to retrieve.
// notification.AuthenticationTicket.Identity.AddClaim(new Claim(
// type: OpenIdConnectParameterNames.AccessToken,
// value: payload.Value<string>(OpenIdConnectParameterNames.AccessToken)));
// }
// }
// }

//});

}
}

最佳答案

TL;DR:使用 ResponseType = "id_token token" 它应该可以工作。

在 OpenID Connect 中,response_type=token 不被视为合法值:http://openid.net/specs/openid-connect-core-1_0.html#Authentication .

有时出于向后兼容的原因,MSFT 开发的 OIDC 中间件不支持 response_type=token:当没有返回 id_token 时总是抛出异常OpenID Connect 提供程序(也排除有效的 code 流)。您可以找到关于此其他的更多信息 SO post .

(备注:在 SecurityTokenValidated 中,您正在使用 n.AuthenticationTicket = new AuthenticationTicket(...) 替换由 OIDC 中间件创建的票据:它不是推荐的方法,将导致 ClaimsIdentity 缺少基本声明。您应该考虑删除分配并简单地添加新声明,就像您为 access_token 声明所做的那样)

关于c# - OWIN OpenID 连接授权无法授权安全 Controller /操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34058960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com