参照 草根专栏- ASP.NET Core + Ng6 实战:https://v.qq.com/x/page/i07702h18nz.html
1、 OIDC-Client
https://github.com/IdentityModel/oidc-client-js
npm install oidc-client --save
2、建立 open-id-connect.service.ts
ng g s shared/oidc/openIdConnect
3、 environment,配置oidc客户端
export const environment = { production: false , apiUrlBase: '/api', openIdConnectSettings: { authority: 'https://localhost:5001/', client_id: 'blog-client', redirect_uri: 'http://localhost:4200/signin-oidc', scope: 'openid profile email restapi', response_type: 'id_token token', post_logout_redirect_uri: 'http://localhost:4200/', automaticSilentRenew: true, silent_redirect_uri: 'http://localhost:4200/redirect-silentrenew' } };
4、BlogIdp项目,config.cs 文件配置客户端访问:
// Angular client using implicit flow new Client { ClientId = "blog-client", ClientName = "Blog Client", ClientUri = "http://localhost:4200", AllowedGrantTypes = GrantTypes.Implicit, AllowAccessTokensViaBrowser = true, RequireConsent = false, AccessTokenLifetime = 180, RedirectUris = { "http://localhost:4200/signin-oidc", "http://localhost:4200/redirect-silentrenew" }, PostLogoutRedirectUris = { "http://localhost:4200/" }, AllowedCorsOrigins = { "http://localhost:4200" }, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, "restapi" } }
5、Blogidp项目配置跨域:
services.AddCors(options => { options.AddPolicy("AngularDev", policy => { policy.WithOrigins("http://localhost:4200") .AllowAnyHeader() .AllowAnyMethod(); }); });
public void Configure(IApplicationBuilder app) { app.UseCors(); }
6、open-id-connect.service.ts 添加登陆操作:
import { Injectable } from '@angular/core'; import { UserManager, User } from 'oidc-client'; import { environment } from '../../../environments/environment'; import { ReplaySubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class OpenIdConnectService { private userManager: UserManager = new UserManager(environment.openIdConnectSettings); private currentUser: User; userLoaded$ = new ReplaySubject<boolean>(1); get userAvailable(): boolean { return this.currentUser != null; } get user(): User { return this.currentUser; } constructor() { this.userManager.clearStaleState(); this.userManager.events.addUserLoaded(user => { if (!environment.production) { console.log('User loaded.', user); } this.currentUser = user; this.userLoaded$.next(true); }); this.userManager.events.addUserUnloaded((e) => { if (!environment.production) { console.log('User unloaded'); } this.currentUser = null; this.userLoaded$.next(false); }); } triggerSignIn() { this.userManager.signinRedirect().then(() => { if (!environment.production) { console.log('Redirection to signin triggered.'); } }); } handleCallback() { this.userManager.signinRedirectCallback().then(user => { if (!environment.production) { console.log('Callback after signin handled.', user); } }); } handleSilentCallback() { this.userManager.signinSilentCallback().then(user => { this.currentUser = user; if (!environment.production) { console.log('Callback after silent signin handled.', user); } }); } triggerSignOut() { this.userManager.signoutRedirect().then(resp => { if (!environment.production) { console.log('Redirection to sign out triggered.', resp); } }); } }
7、添加 signin-oidc component
8、添加 redirect-silent-renew component
9、 ng g guard shared/oidc/RequireAuthenticatedUserRoute --spec false
触发登陆界面;
app.module Provided 添加 RequireAuthenticatedUserRouteGuard , OpenIdConnectService
10、blog-routing.module.ts 注册路由:
const routes: Routes = [ { path: '', component: BlogAppComponent, children : [ {path: 'post-list' , component: PostListComponent, canActivate: [RequireAuthenticatedUserRouteGuard] }, {path: '**' , redirectTo: 'post-list' } ] }
11、配置登陆路由: app.module
const routers: Routes = [ { path: 'blog', loadChildren: './blog/blog.module#BlogModule' }, { path: 'signin-oidc', component: SigninOidcComponent }, { path: 'redirect-silentrenew', component: RedirectSilentRenewComponent }, { path: '**', redirectTo: 'blog' } ];
12、添加拦截器:authorization-header-interceptor.interceptor.ts ,在blog.module.ts 里面配置
providers: [ PostService, { provide: HTTP_INTERCEPTORS, useClass: AuthorizationHeaderInterceptor, multi: true } ]