【问题标题】:mitreId openid connect server using in an angular and .net webapi application在 Angular 和 .net webapi 应用程序中使用 mitreId openid 连接服务器
【发布时间】:2018-06-07 04:42:17
【问题描述】:

我正在开发一个项目,该项目在 asp.net WebAPI 中具有 Angular 作为前端和后端 API。有一个托管的 OpenId 连接服务器(mitreid),我必须使用该服务器进行身份验证和授权。

我正在尝试将 OpenId Connect 服务器身份验证配置为 .net WebAPI, 这就是我在 WebAPI 的 StartUp.cs 中所做的

app.SetDefaultSignInAsAuthenticationType("OpenIdConnect");
app.UseOpenIdConnectAuthentication(
               new OpenIdConnectAuthenticationOptions
               {
                   ClientId = "some_client",
                   ClientSecret = "some_secret",
                   Authority = "http://localhost:8181/openid-connect-server-webapp",                      
                   UseTokenLifetime = true,
                   ResponseType = "code",
                   Scope = "openid email",
                   SignInAsAuthenticationType = "OpenIdConnect",
                   TokenValidationParameters = new TokenValidationParameters
                   {
                       ValidateIssuer = false,
                       ValidateAudience = false
                   },
                   Notifications = new OpenIdConnectAuthenticationNotifications()
                   {
                       AuthorizationCodeReceived = (context) =>
                       {
                           var code = context.Code;
                           return Task.FromResult(0);
                       },
                       RedirectToIdentityProvider = async n =>                       
                       {
                           n.ProtocolMessage.RedirectUri = "http://localhost:54464/";
                           n.OwinContext.Authentication.Challenge(new String[] { "OpenIdConnect" });
                       },
                       SecurityTokenValidated = (n) =>
                       {
                           var nid = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, "user", "user");                                  
                           nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                           nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));    
                           nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));
                           nid.AddClaim(new Claim("app_specific", "some data"));
                           n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties);
                           return Task.FromResult(0);
                       },
                       SecurityTokenReceived = (context) =>
                       {
                           var code = context;    
                           return Task.FromResult(0);
                       },
                       AuthenticationFailed = (context) =>
                       { 
                           //some redirect
                           context.HandleResponse(); 
                           return Task.FromResult(0);
                       }
                   }
               });

我什至尝试设置配置,如下所示

ConfigurationManager = 
new ConfigurationManager<OpenIdConnectConfiguration>
    ("http://localhost:8181/openid-connect-server-webapp/.well-known/openid-configuration"),
Configuration = new OpenIdConnectConfiguration
{
    Issuer = "http://localhost:8181/openid-connect-server-webapp",
    AuthorizationEndpoint = "http://localhost:8181/openid-connect-server-webapp/authorize",
    TokenEndpoint = "http://localhost:8181/openid-connect-server-webapp/token",
    UserInfoEndpoint = "http://localhost:8181/openid-connect-server-webapp/userinfo"
},

当我尝试调试 API(在端口 54464)时,我将授权 attr 放在控制器上,它正在重定向到 OpenID 登录页面,然后在成功登录后,然后没有执行控制器操作。 假设这是我正在测试的 API 调用 http://localhost:54464/api/common/getlist 最初用于第一次调用 API 重定向到登录页面,然后重定向到 http://localhost:54464/api/common/getlist/?code=V7KFPZ&amp;state=OpenIdConnect.AuthenticationProperties%3D****somecode**** 而不是返回 JSON 数组。

我尝试使用来自邮递员的上述重定向 URL 中的代码生成不记名令牌,这很成功。但是,当尝试使用 postman 在授权标头中使用令牌时,响应是 OpenID 登录 HTML 页面。

除了RedirectToIdentityProvider之外没有执行通知事件的问题

我知道我遗漏了一些东西,请指出那些,我对此很陌生。如果我做错了什么、一些配置错误或任何实现 OpenId 客户端的解决方案,请告诉我。

【问题讨论】:

  • 您正在使用授权码流。我想您的 Angular 应用程序是一个独立的 SPA,甚至没有托管在与您的 WebAPI 应用程序相同的主机名和端口下。对于这样的场景,有隐式流。 Angular 应用程序将自行处理登录并获取 ID 和访问令牌。然后它将访问令牌发送到 API 以获取资源。我使用oidc-client(NPM)作为客户端库,使用IdentityServer3.AccessTokenValidation(NuGet)作为api。如果您想朝这个方向发展,请告诉我,我会提供答案。
  • 是的,您能否就这种方法提供一些见解。

标签: angular asp.net-web-api2 openid-connect openid-provider mitreid-connect


【解决方案1】:

如上面评论中所述,授权代码流程不太适合 Angular 应用程序等 Javascript 客户端。因此,这描述了 Implicit Flow

的可能设置

这是您可以使用流行库的方法:

授权服务器 (Mitreid):我对 Mitreid 一无所知,但您必须使用 ID some_client 注册您的客户端应用程序或更改您现有的客户端配置以使用隐含流程。像 Identity Server 这样的一些实现将需要一个额外的参数来允许将访问令牌传递给浏览器。此外,请确保将 http://YOUR_ANGULAR_APP/auth-callback 注册为重定向 URI。您可能还想为您的 WebApi 应用程序注册一个范围,以便它可以使用访问令牌。我假设您有一个名为webapi 的范围。我还将假设您将使用 JWT 而不是引用令牌。在后一种情况下,WebAPI 配置略有不同。

客户端(Angular):我推荐您可以通过 NPM 安装的 oidc-client 库。这是一个如何将其集成到 Angular 中的教程:https://www.scottbrady91.com/Angular/SPA-Authentiction-using-OpenID-Connect-Angular-CLI-and-oidc-client。我根据您的示例更新了设置:

export function getClientSettings(): UserManagerSettings {
    return {
        authority: 'http://localhost:8181/openid-connect-server-webapp',
        client_id: 'some_client',
        redirect_uri: 'http://YOUR_ANGULAR_APP/auth-callback',
        post_logout_redirect_uri: 'http://YOUR_ANGULAR_APP/',
        response_type:"id_token token",
        scope:"openid email webapi",
        filterProtocolClaims: true,
        loadUserInfo: true
   };
}

Angular 应用程序将启动登录过程,如果一切正常,它会为您留下一个 ID 令牌和一个访问令牌。 oidc-client 还准备了一个带有访问令牌的 Authorization 标头,您必须将其添加到对 WebAPI 应用程序的所有授权请求中。 oidc-client 也会自动加载用户声明。

资源服务器(WebAPI 应用程序):WebAPI 端实现非常简单,您只需添加访问令牌验证中间件和[Authorize] 属性即可。对于 ASP.NET Core 之前的应用,我喜欢使用 IdentityServer3.AccessTokenValidation,您可以通过 Nuget 安装它。

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "http://localhost:8181/openid-connect-server-webapp",
            RequiredScopes = "openid email webapi"
        });

如果您将 [Authorize] 端点添加到您的 WebAPI,您应该根据 JWT 中包含的声明获得 ClaimsIdentity 作为 User

【讨论】:

  • 我会试试这个然后回来。问题是 openId 服务器没有实现令牌响应类型。所以,我们必须手动验证令牌
猜你喜欢
  • 2019-07-30
  • 2014-10-03
  • 2019-08-16
  • 2017-11-04
  • 2021-09-30
  • 2019-05-19
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多