繁体   English   中英

如何将 Saml 身份验证添加到 asp.net Web API 应用程序

[英]How to add Saml Authentication to asp.net Web API application

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

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

我已经尝试使用 SustainSys: 将 SAML 身份验证添加到 .net WebAPI

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

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

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

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

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

技术方案

1) 实现Web应用到Web API认证场景

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

3) 使用 adal-angular4 (version 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 标头中。

第四步:

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 { }

第四步:

验证 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。

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

[Authorize]
[ApiController]
public class MyController : ControllerBase

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM