参照 草根专栏- 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 } ]