使用角度和.net webapi应用程序中的mitreId openid连接服务器

时间:2017-12-26 10:05:16

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

我正在开发一个在asp.net WebAPI中具有角度作为前端和后端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)时,我将authorize attr放在控制器上,它将重定向到OpenID登录页面,然后在成功登录后,然后没有执行任何控制器操作。 让我们说这是我正在测试的API调用 http://localhost:54464/api/common/getlist最初用于首次调用API重定向到登录页面,然后重定向到http://localhost:54464/api/common/getlist/?code=V7KFPZ&state=OpenIdConnect.AuthenticationProperties%3D****somecode****而不是返回JSON数组。

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

RedirectToIdentityProvider

以外,没有任何通知事件正在执行

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

1 个答案:

答案 0 :(得分:1)

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

的可能设置

这就是你如何使用流行的库来实现它:

授权服务器(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 App将启动登录过程,如果一切正常,您将获得ID令牌和访问令牌。 oidc-client还会为访问令牌准备一个Authorization标头,您必须将其添加到对您的WebAPI应用程序的所有授权请求中。 oidc-client还会自动加载用户声明。

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

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

如果您向WebAPI添加[Authorize]个终结点,则应根据JWT中包含的声明获得ClaimsIdentity User