以Azure为例的SSO

由于文章的篇幅有限,无法将全部的代码贴上来,如想要看完整案例,请在公众号文章中留言(其他平台很少看…毕竟最近印度同事的UI组件库搞得我好烦)


1.关于SSO

单点登录又称之为SSO,全称为 Single Sign On ,一般在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

比如,当我们使用一个腾讯旗下的产品时,我们一般会接入QQ登陆,此时就可以认为QQ登陆为我们的SSO。只要我们登录了QQ,就可以根据凭证获取到你在QQ中的信息,并登录该平台。

2.SSO流程

无论使用第三方或者是自己的sso,下面将以一个开发人员的角度,以QQ作为例子讲解一个SSO的过程,

1.当用户第一次登录平台A的时候,由于该平台使用了QQ的服务去获取用户信息,该平台会自动调用QQ的服务(比如跳转QQ登录),此时我们会设置一个RedirectURL的参数到qq的login服务上。

2.当用户从qq登录后,qq的后台服务会根据我们的 RedirectURL 参数,将一个token传到我们的Redirect的地址。

3.当我们的服务接收到了来自QQ服务器的一个重定向请求,且该请求还会带一个token,我们可以根据QQ文档去调用Api获取我们想要的信息,比如获取用户信息等。

4.当我们获取到用户的信息之后,我们用 JsonWebToken 的形式重新去设置我们的token,并且使用其作为前后端通讯的token。

在上述的过程中,我们使用第三方的SSO,是基于以下几个原因

  • qq本质上提供了用户的信息给我们,并且提供了一个便捷的,获取用户信息的api。
  • QQ作为一个维护多年的平台,对于权限以及用户管理等模块已经很完善了
  • 我们自己开发的话,我们需要花费大量的时间和精力,还不能保证一定没问题

3.关于Azure

上面的过程中,已经知道SSO的流程,想必大家都已经对SSO有了初步的认知,而选择一个SSO是要根据市场以及客户所用的SSO有关,比如对于外企,我们会选择Azure作为SSO,而不是选择很少外国人用的QQ。

Microsoft Azure 作为微软云计算,大公司背书.

最主要是我们的客户选择使用它,所以下面的例子会以其作为例子

4.使用SSO

不同平台的sso参数思路‘大差不差’,都是用 AppID + AppScrect 这一套,所以下面的例子也按照这个套路来介绍。

1.准备各类参数,其中最主要的参数是CLIENT_ID,TENANT_ID,CLIENT_SECRET。

//当前域名
LOGIN_REDIRECT=https://xxx.com
//重定向地址
OAUTH2_REDIRECT_URL=https://xxx.com/user/login_callback
//client_id,在app的详情中查看,由管理员给的
OAUTH2_CLIENT_ID=6aaaaaae-7aaa-4aaa-baaa-aaaaaaaaad89
//tent_id,可以理解为密钥。由管理员给的
OAUTH2_TENANT_ID=4266ec6c-fe9f-4893-82e9-996189e0b81b
//在Azure上生成的,验证机器是否允许登录
OAUTH2_CLIENT_SECRET=mvaaa~.qLgH8aaaaaaaaaTpnWaLD9Em-H3Z6gb_T

2.准备我们的登陆接口重定向到auzre的登陆接口

当用户调用我们的登陆接口时,我们会马上调用到Azure的服务去登陆。

  @Get('user/login')
  login(@Response() res) {
    res.redirect(this.userServie.processLogin());
  }
​

此时,浏览器的弹窗如下:

3.登陆成功后获取到用户的凭证

@Get('user/login_callback')
  async loginCallback(@Request() req, @Response() res) {
    let code = '';
    if (req.query.code) {
      code = req.query.code;
      const tokenInfo = await this.userServie.getAccessTokenByCode(code, req.log);
      // if redirect error, check cookie has refresh_token
      if (tokenInfo.error) {
        req.log.error(`user login callback error will redirect to login`);
        res.redirect('/login');
      } else {
        const { claimsInfo, user, groups } = this.userServie.processAccessToken(tokenInfo.access_token);
​
        if (!groups.includes(environmentConfig.azure.adGroupName)) {
          req.log.error('User not in AD group');
          res.status(400).json({ message: 'User not in AD group' });
        }
​
​
        req.log.info(`login user name is ${user.id}`);
        const redirectUrl = `${environmentConfig.cx.frontend_url}?t=${claimsInfo}`;
        res.redirect(redirectUrl);
      }
    } else {
      req.log.error('ADFS grant code not found');
      res.status(400).json({ message: 'ADFS grant code not found' });
    }
  }
​

上述代码中,流程在于获取到了azure的token之后,调用api获取用户信息,并生成新的token并给到前端。

4.根据凭证获取到用户的信息。

在上述代码中,我们完成了整个流程,但是最主要的核心代码如下

processAccessToken(azureToken) {
    const auzraUserInfo = JWT.decode(azureToken);
    const {
      onPremisesSamAccountName = '',
      cn = '',
      name = '',
      family_name = '',
      given_name = '',
      username = '',
      groups = []
    } = auzraUserInfo;
    let adKeyWord = '';
    let userName = '';
      adKeyWord = name;
      userName = `${given_name} ${family_name}`;
    const jwtToken = JWT.sign(
      {
        cn: adKeyWord,
        sAMAccountName: adKeyWord,
        username: userName,
        auth: 'saml',
        thumbnail: ''
      },
      environmentConfig.cx.jwt_token_secret,
      // { expiresIn: 7 * 24 * 60 * 60 }
      { expiresIn: 1 * 24 * 60 * 60 }
    );
    return { claimsInfo: jwtToken, user: { id: userName }, groups: groups };
  }

至此,一个流程就结束了,我们将生成的 token 放到前端就可以了。

需要注意的是,我们的凭证是有expiry date的。

多谢关注~ 公众号求关注~

公众号文章

### C# ASP.NET集成Azure AD SSO实现指南 #### 配置Azure Active Directory (AAD) 为了使ASP.NET应用程序能够支持Azure AD单点登录(SSO),需先在Azure门户中注册应用并配置必要的权限。这一步骤涉及创建一个新的企业应用,设置重定向URI以及记录下客户端ID和租户ID等重要参数[^1]。 #### 安装Microsoft.Identity.Web NuGet包 为了让开发更加简便高效,在项目里引入`Microsoft.Identity.Web`库是一个不错的选择。此NuGet包提供了丰富的API来处理OAuth 2.0授权流程中的细节工作,从而简化了与Azure AD交互的过程。可以通过Visual Studio内置的管理工具轻松安装该依赖项: ```bash Install-Package Microsoft.Identity.Web ``` #### 修改Startup.cs文件以启用身份验证中间件 接下来,在项目的入口处——即`Startup.cs`文件内,添加如下所示的服务注入语句,以便于后续调用Identity Web所提供的功能接口;同时还要记得更新Configure方法里的管道配置部分,确保HTTP请求可以被正确转发给相应的处理器实来进行安全校验操作。 ```csharp public void ConfigureServices(IServiceCollection services) { string[] initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' '); services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddInMemoryTokenCaches(); services.AddControllersWithViews(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); // Add Authentication middleware here app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } ``` #### 更新appsettings.json文件 最后但同样重要的一步是在应用程序根目录下的`appsettings.json`文件中补充关于Azure AD的相关设定信息,比如客户端ID(Client ID)、域名(Tenant ID/Domains)以及其他可能需要用到的身份认证选项。 ```json { "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "[Enter your tenant domain]", "TenantId": "[Enter 'common' or a specific Tenant Id]", "ClientId": "[Enter client id]" }, ... } ``` 完成上述所有步骤之后,重启服务器端程序即可生效新的更改。此时当用户尝试访问受保护资源时会被自动跳转至微软在线服务页面进行账号密码输入环节,成功后则会返回原网页继续浏览体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值