5. .NET5+Vue配置Identity server授权中心

什么是Identity server4


dentityServer4 是为ASP.NET Core 系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证框架。

将identityserver部署在你的应用中,具备如下的特点

认证服务
可以为你的应用(如网站、本地应用、移动端、服务)做集中式的登录逻辑和工作流控制。IdentityServer是完全实现了OpenID Connect协议标准。
单点登录登出(SSO)
在各种类型的应用上实现单点登录登出。
API访问控制
为各种各样的客户端颁发access token令牌,如服务与服务之间的通讯、网站应用、SPAS和本地应用或者移动应用。

开始实战

Vue篇
首先安装OIDC-Client
npm install oidc-client

接着在dev.env.jsprod.env.js中配置OIDC

 OIDC: {
       //使用identityserver配置
    authority: '"https://localhost:6055"',
    client_id: '"vue"',
    redirect_uri: '"http://localhost:8088/callback"',
    post_logout_redirect_uri: '"http://localhost:8088/home/index"',
    response_type: '"id_token token"',
    scope: '"openid profile UserService OrderService GoodsService"'
  },

authority为后端Ids身份认证地址,
client_id为配置的客户端,需要和后台保持一致,
redirect_uri 为登录成功的返回地址。
scope 为请求的token所包含的资源

components下新增call-back.vue,代码如下。

  <template>
  <div></div>
</template>

<script>
import Oidc from "oidc-client";
import store from '../store'

new Oidc.UserManager()
  .signinRedirectCallback()
  .then(function (response) {
     
    if (response.access_token) {
     
      //保存token
      store.commit('setAssessToken',response.access_token);
       //保存Id_token
      store.commit('setIdToken',response.id_token);
      //保存用户昵称
      store.commit('setUserName',response.profile.name);
        //保存用户Id
      store.commit('setUserId',response.profile.sub);
    }
    window.location = "/Home/Index";
  })
  .catch(function (e) {
     });
export default {
     };
</script>

store.js里就是暂时用localstorage存储token和一些简单的用户信息。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
     
  state: {
     
    assess_token: '',  //初始化token
  },
  mutations: {
     
    //存储token方法
    //设置token等于外部传递进来的值
    setAssessToken(state, assess_token) {
     
      state.assess_token = assess_token
      localStorage.assess_token = assess_token //同步存储token至localStorage
    }
  },
  getters: {
     
    //获取token方法
    //判断是否有token,如果没有重新赋值,返回给state的token
    getAssessToken(state) {
     
      if (!state.assess_token) {
     
        state.assess_token = localStorage.getItem('assess_token')
      }
      return state.assess_token
    }
  },
  actions: {
     

  }
})

接着在主界面点击登录的时候,关键代码如下。

import Oidc from "oidc-client";

let config = process.env.OIDC;
let mgr = new Oidc.UserManager(config);
//登录
mgr.signinRedirect();
//退出登录
mgr.signoutRedirect({
      id_token_hint: store.getters.getIdToken });
.NET5后端配置Ids4
首先需要在`EasyShop.IdentityServer`项目下引入nuget包。
 <PackageReference Include="IdentityServer4" Version="4.1.2" />
 <PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
 <PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.2" />

新建文件夹Configuration,在文件夹下新建类InMemoryConfiguration.cs,用来进行Ids4的客户端资源等配置,这些资源也可以放到数据库里。

using IdentityServer4;
using IdentityServer4.Models;
using System.Collections.Generic;

namespace EasyShop.IdentityServer.Configuration
{
     
    public class InMemoryConfiguration
    {
     
        public static IEnumerable<ApiResource> ApiResources =>
        new ApiResource[]
        {
     
            new ApiResource("UserService","#UserService")
            {
     
                Scopes = {
      "UserService" }
            },
            new ApiResource("OrderService","#OrderService")
            {
     
                Scopes = {
      "OrderService" }
            },
            new ApiResource("GoodsService","#GoodsService")
            {
     
                Scopes = {
      "GoodsService" }
            },
        };


        public static IEnumerable<Client> Clients()
        {
     
            return new[]
            {
     
                  // machine to machine client
                new Client
                {
     
                    ClientId = "client",
                    ClientSecrets = {
      new Secret("secret".Sha256()) },

                    AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                    // scopes that client has access to
                    AllowedScopes = {
      "UserService", "GoodsService","OrderService" },
                },
                new Client
                {
     
                    ClientId="vue",
                    ClientName="vue 客户端",
                    AllowedGrantTypes = GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser=true,
                    AccessTokenType = AccessTokenType.Jwt,
                    AllowOfflineAccess=true,
                    RedirectUris = {
      "http://localhost:8088/callback" },
                    PostLogoutRedirectUris = {
      "http://localhost:8088/home/index" },
                    AllowedCorsOrigins = {
      "http://localhost:8088" },

                    AllowedScopes =
                    {
     
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "UserService",
                        "OrderService",
                        "GoodsService"
                    }
                }
            };
        }
       
        public static IEnumerable<IdentityResource> IdentityResources()
        {
     
            return new List<IdentityResource>
            {
     
                new IdentityResources.OpenId(),
                new IdentityResources.Profile()
            };
        }
        public static IEnumerable<ApiScope> ApiScopes =>
          new ApiScope[] {
     
                new ApiScope("GoodsService"),
                new ApiScope("OrderService"),
                new ApiScope("UserService")
          };
    }
}

在配置文件InMemoryConfiguration.cs里可以看到,我并没有配置用户,因为用户需要从数据库中查询,接着需要配置startup.cs.

using EasyShop.IdentityServer.App;
using EasyShop.IdentityServer.Configuration;
using IdentityServer4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;

namespace EasyShop.IdentityServer
{
     
    public class Startup
    {
     
        public Startup(IConfiguration configuration)
        {
     
            Configuration = configuration;
        }

        public IConfiguration Configuration {
      get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
     
            services.AddControllersWithViews();

           var builder =  services.AddIdentityServer()
              .AddInMemoryClients(InMemoryConfiguration.Clients())
              .AddInMemoryApiResources(InMemoryConfiguration.ApiResources)
              .AddInMemoryApiScopes(InMemoryConfiguration.ApiScopes) //这个方法是新加的
              .AddInMemoryIdentityResources(InMemoryConfiguration.IdentityResources())
              .AddProfileService<CustomProfileService>();

            builder.AddSigningCredential(new X509Certificate2(@"D:\MyProject\Microservice\EasyShop\EasyShop\EasyShop.Api\easyshop.pfx", "1234"));  //1234 为证书密码

            services.AddTransient<UserApp>();

            services.AddDbContext<MySqlDBContext>(options =>
                 options.UseMySQL(Configuration.GetConnectionString("MysqlConnectionString")));
            services.AddSession();
            services.AddMvc(options => options.EnableEndpointRouting = false);
            //JS-allow Ajax calls to be made from http://localhost:8088 to http://localhost:6055
            services.AddCors(options =>
            {
     
                //this defines a CORS policy called "default"
                options.AddPolicy("default", policy =>
                {
     
                    policy.WithOrigins("http://localhost:8088")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            });
        }

        // 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();
            };
            app.UseStaticFiles();
            app.UseRouting();
            //JS-Add the CORS middleware to the pipeline in Configure:
            app.UseCors("default");
            app.UseMvcWithDefaultRoute();

            app.UseIdentityServer();
            app.UseAuthorization();

            app.UseHttpsRedirection();
            app.UseSession();
            app.UseEndpoints(endpoints =>
            {
     
                endpoints.MapControllers();
            });
        }
    }
}

然后需要把Ids4的官方的页面加进来,直接找到IdentityServer4.Quickstart.UI-main,拷贝进来即可,若需要让用户是用的数据库中的用户,则需要修改下AccountController.cs
接着就可以尝试启动了,若点击登录可以正常调整到下面这个页面,说明大部分是配置成功的。
5. .NET5+Vue配置Identity server授权中心_第1张图片
接着还应该测试是否可以正常调整到返回地址,以及Assess_Token是否可以正常获取到。

课后总结


Ids4所能做能实现的功能还有很多,需要去慢慢的深入研究,不同版本之间也有一定的差距,本文仅作参考。

项目地址:https://gitee.com/limeng66/easy-shop

你可能感兴趣的:(微服务,vue,.NET5,微服务,Ids4,OIDC)