【问题标题】:How to add Saml Authentication to asp.net Web API application如何将 Saml 身份验证添加到 asp.net Web API 应用程序
【发布时间】:2019-09-05 07:37:57
【问题描述】:

我有一个带有 asp.net Web Api 后端和 Angular 前端的 Web 应用程序。 该应用程序使用基于表单的身份验证,根据其数据库检查用户的身份。

我的任务是向应用程序添加 Saml 身份验证,并将 Azure AD 作为我的身份提供者。

我已经尝试过使用 SustainSys: Add SAML Authentication to .net WebAPI

我使用这种方法的问题是 Angular SPA 不是由 Saml 身份验证的最终重定向触发的,因此不会执行登录操作。

我正在评估的另一个选项是 Adal: https://www.npmjs.com/package/microsoft-adal-angular6

在这种情况下,我不知道应该在 Web API 中实现什么来执行身份验证。

添加此类身份验证的正确方法是什么?

【问题讨论】:

    标签: angular asp.net-web-api azure-active-directory


    【解决方案1】:

    您可以采取以下措施来确保您的 Angular SPA 和 asp.net core web api 安全。

    技术解决方案

    1) 实现Web application to web API authentication scenario

    2) 使用https://portal.azure.com 配置认证过程。

    3) Use adal-angular4(版本 3.0.1+)Angular 包,用于在 Angular 应用程序中实现身份验证。

    4) 使用 Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet 包实现对 Asp.Net 核心 Web API 服务的身份验证。

    先决条件

    注册 Angular 应用程序

    https://portal.azure.com 在 Azure Active Directory 中注册应用程序 转到“Azure Active Directory”->“应用注册”并选择添加“新应用注册”。

    注册 Web API

    https://portal.azure.com 在 Azure Active Directory 中注册 Web API 服务。 注册过程类似于注册 Angular 应用程序。 (见上文)

    配置对 Web API 资源的访问

    客户端应用程序通过声明权限请求来获得对资源服务器的访问权限。 转到 Azure Active Directory -> 应用注册并选择 Angular 应用程序的设置。

    选择 Angular 应用程序访问的 Web API:

    使用委派权限启用访问

    在注册的 Angular 应用程序清单中添加所需的资源(Web API)访问权限:

    授予对 Web API 资源的访问权限

    安装adal包

    安装 adal 包 adal-angular4(版本 3.0.1+)。包 adal-angular4 已更新为与 angular6 兼容。发现正确的包是令人困惑的,因为包名称是指 angular 4,而且还有另一个包 adal-angular5 与 angular 6 不兼容。

    技术解决方案

    认证过程

    第一步:

    当用户第一次通过浏览器访问应用程序时,Angular 应用程序检测到它没有经过身份验证并重定向到 Microsoft 登录以进行凭据介绍。

    第 2 步:

    在登录步骤之后,身份验证服务将流程重定向到配置的 Angular 应用程序回调,在此完成身份验证流程。

    第 3 步:

    Angular 应用程序调用所需的 Web API。身份验证令牌在调用 Web API 之前添加到 HTTP 标头中。

    第 4 步:

    Web API 验证身份验证令牌,并在成功的情况下返回请求的资源。

    实施

    第 1 步:

    a) 配置 ADAL 服务

    import { Component } from '@angular/core';
    import { AdalService } from 'adal-angular4';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      title = 'app';
    
      private adalConfig = {
        tenant: '[TENANT_GUID]',
        clientId: '[CLIENTID_GUID]',
        redirectUri: "[LOGIN_REDIRECT_URL]",
        postLogoutRedirectUri: "[POST_LOGOUT_REDIRECT_URL]",
        endpoints: {
          "[HOME_URL_WEB_API]": "[HOME_WEB_API_GUID]"
        }
      }
    
      constructor(private adal: AdalService) {
        this.adal.init(this.adalConfig);
      }
    
      signOut(): void {
        this.adal.logOut();
      }
    }
    

    [TENANT_GUID] 是 Azure AD 目录 ID。

    b) 实现一个防护,在出现未经身份验证的请求时重定向到登录

    import { Injectable } from '@angular/core';
    import { CanActivate } from '@angular/router';
    import { AdalService } from 'adal-angular4';
    
    @Injectable({
      providedIn: 'root'
    })
    export class AuthGuard implements CanActivate {
    
      constructor(private adal: AdalService) { }
    
      canActivate(): boolean {
    
        if (this.adal.userInfo.authenticated) {
          return true;
        }
    
        this.adal.login();
    
        return false;
      }
    
    }
    

    c) 保护路由器类中的应用路径:

    const routes: Routes = [
      { path: '', component: MyComponent, canActivate: [AuthGuard] },
      { path: 'auth-callback', component: AuthCallbackComponent },
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule {}
    

    第 2 步:- 完成登录过程。

    实现一个回调组件,该组件将作为登录过程的一部分被调用。 回调 URL 的注册在步骤 1 中使用 redirectUri 信息配置 adal 时完成。

    import { Component, OnInit, NgZone } from '@angular/core';
    import { Router } from '@angular/router';
    import { AdalService } from 'adal-angular4';
    
    @Component({
      selector: 'app-auth-callback',
      templateUrl: './auth-callback.component.html',
      styleUrls: ['./auth-callback.component.css']
    })
    export class AuthCallbackComponent implements OnInit {
    
      constructor(private router: Router, private adal: AdalService, private _zone: NgZone) { }
    
      ngOnInit() {
        this.adal.handleWindowCallback();
    
        setTimeout(() = {
          this._zone.run(
            () = this.router.navigate(['/'])
          );
        }, 200);
      }
    
    }
    

    handleWindowCallback() 将身份验证令牌添加到会话。

    第 3 步:

    为发送到 Web API 的 HTTP 请求设置身份验证令牌 Adal 使它成为一个简单的步骤。唯一要做的步骤是在 app.module.ts 文件中注册开箱即用的 AdalInterceptor:

    从 '@angular/platform-b​​rowser' 导入 { BrowserModule }; 从'@angular/core'导入{ NgModule }; 从“@angular/common/http”导入 { HttpClientModule }; 从“@angular/forms”导入 { FormsModule };

    import { AppComponent } from './app.component';
    import { AppRoutingModule } from './/app-routing.module';
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    import { AuthCallbackComponent } from './auth-callback/auth-callback.component';
    import { AdalService, AdalInterceptor } from 'adal-angular4';
    
    @NgModule({
      declarations: [
        AppComponent,
        AuthCallbackComponent
      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        AppRoutingModule,
        FormsModule
      ],
      providers: [AdalService, { provide: HTTP_INTERCEPTORS, useClass: AdalInterceptor, multi: true }],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    第 4 步:

    在 Web API 服务中验证身份验证令牌 在 Web API Startup.cs 文件中将身份验证服务配置为 AzureADBear:

    public void ConfigureServices(IServiceCollection services)
    {
    
        services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
        .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
    
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddCors(options = 
        {
            options.AddPolicy("AllowAllOrigins",
             builder =
             {
                 builder.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
             });
        });
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }
    
        app.UseHttpsRedirection();
    
        app.UseCors("AllowAllOrigins");
        app.UseAuthentication();
    
        app.UseStaticFiles();
        app.UseMvc(routes =
        {
            routes.MapRoute(name: "default", template: "api/{controller}/{id}");
        });
    }
    

    请确保您已安装先决条件部分中提到的 Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet 包。 在 appsettings.json 中添加 AzureAD 部分,以便为验证过程提供身份验证详细信息:

    "AzureAd": {
      "Instance": "https://login.microsoftonline.com",
      "Domain": "[AD_DOMAIN]",
      "TenantId": "[TENANTID_GUID]",
      "ClientId": "[CLIENTID_GUID]"
    }
    

    将上述占位符替换为以下信息:

    [AD_DOMAIN] 是 Azure AD 域。

    [TENANT_GUID] 是 Azure AD 目录 ID。 (见上文)

    [CLIENTID_GUID] 是 Web API 的应用程序 ID。

    最后用 filter 属性装饰你的控制器,如下所示:

    [Authorize]
    [ApiController]
    public class MyController : ControllerBase
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 2019-01-14
      相关资源
      最近更新 更多