将identityserver部署在你的应用中,具备如下的特点
npm install oidc-client
接着在dev.env.js
和 prod.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 });
<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
。
接着就可以尝试启动了,若点击登录可以正常调整到下面这个页面,说明大部分是配置成功的。
接着还应该测试是否可以正常调整到返回地址,以及Assess_Token
是否可以正常获取到。
项目地址:https://gitee.com/limeng66/easy-shop