우리 회사는 LDAP와 연결된 인증을 위해 Keycloak을 사용하고 기업 데이터로 채워진 사용자 개체를 반환합니다. 그러나이 기간 동안 우리는 모두 집에서 일하고 있으며, 앱을 다시로드 할 때마다 회사 서버에서 인증을 받아야하는 일상 업무에서 비용이 많이 드는 오버 헤드로 입증되었습니다. 특히 간헐적 인 인터넷 연결의 경우.
Keycloak 호출을 가짜로 만들고 성공한대로 keycloak.protect ()가 작동하도록하려면 어떻게해야합니까?
내 컴퓨터에 Keyclock 서버를 설치할 수 있지만, 그 외에 다른 서버가 실행될 것이기 때문에 그렇게하지 않겠습니다. vagrant VM, Postgres 서버, be server 및 내가 열어 둔 다른 모든 것. 모의 호출을하고 고정 된 하드 코딩 된 객체를 반환하는 것이 가장 좋습니다.
내 프로젝트의 app-init.ts는 다음과 같습니다.
import { KeycloakService } from 'keycloak-angular';
import { KeycloakUser } from './shared/models/keycloakUser';
<...>
export function initializer(
keycloak: KeycloakService,
<...>
): () => Promise<any> {
return (): Promise<any> => {
return new Promise(async (res, rej) => {
<...>
await keycloak.init({
config: environment.keycloakConfig,
initOptions: {
onLoad: 'login-required',
// onLoad: 'check-sso',
checkLoginIframe: false
},
bearerExcludedUrls: [],
loadUserProfileAtStartUp: false
}).then((authenticated: boolean) => {
if (!authenticated) return;
keycloak.getKeycloakInstance()
.loadUserInfo()
.success(async (user: KeycloakUser) => {
// ...
// load authenticated user data
// ...
})
}).catch((err: any) => rej(err));
res();
});
};
고정 된 로그인 사용자 한 명만 있으면됩니다. 그러나 고정 된 사용자 지정 데이터를 반환해야합니다. 이 같은:
{ username: '111111111-11', name: 'Whatever Something de Paula',
email: 'whate[email protected]', department: 'sales', employee_number: 7777777 }
편집하다
@BojanKogoj의 아이디어를 보려고했지만 Angular Interceptor 페이지 및 기타 예제 및 자습서에서 AFAIU를 구성 요소에 삽입해야합니다. Keycloak 초기화는 구성 요소가 아닌 앱 초기화시 호출됩니다. 또한 Keycloak의 반환은 init () 메서드의 직접 반환이 아닙니다. .getKeycloakInstance().loadUserInfo().success()
시퀀스의 다른 개체를 통과 합니다. 아니면 완전히 이해하지 못한 것은 나뿐 일 수도 있습니다. 누군가 호출을 가로 채서 올바른 결과를 반환 할 수있는 인터셉터의 예를 가지고 올 수 있다면 가능성이있을 수 있습니다.
편집 2
내가 필요로하는 것을 보완하는 것은 전체 keycloak의 시스템이 작동하는 것입니다. 것을 통지 바랍니다 (user: KeycloakUser) => {
함수에 전달되는 success
keycloak의 내부 시스템의 방법을. 위에서 말했듯이 경로에는 작동해야하는 keycloak.protect ()가 있습니다. 따라서 사용자와 약속을 반환하는 단순한 경우가 아닙니다. 전체 .getKeycloakInstance (). loadUserInfo (). success () 체인을 모의 처리해야합니다. 아니면 적어도 그것이 내가 그것을 이해하는 방법입니다.
@yurzui의 답변을 기반으로 만든 솔루션에 답변을 포함했습니다.
누군가가 더 나은 해결책을 찾을 수 있는지보기 위해 현상금을 수여하기 위해 며칠을 기다릴 것입니다 (나는 의심 스럽습니다).
Angular 환경 (또는 심지어 process.env
) 변수를 활용 하여 실제 구현과 모의 구현간에 전환 할 수 있습니다 .
다음은이를 수행하는 방법에 대한 간단한 예입니다.
app-init.ts
...
import { environment } from '../environments/environment';
export function initializer(
keycloak: KeycloakService
): () => Promise<any> {
function authenticate() {
return keycloak
.init({
config: {} as any,
initOptions: {onLoad: 'login-required', checkLoginIframe: false},
bearerExcludedUrls: [],
loadUserProfileAtStartUp: false
})
.then(authenticated => {
return authenticated ? keycloak.getKeycloakInstance().loadUserInfo() : Promise.reject();
});
}
// we use 'any' here so you don't have to define keyCloakUser in each environment
const { keyCloakUser } = environment as any;
return () => {
return (keyCloakUser ? Promise.resolve(keyCloakUser) : authenticate()).then(user => {
// ...
// do whatever you want with user
// ...
});
};
}
environment.ts
export const environment = {
production: false,
keyCloakUser: {
username: '111111111-11',
name: 'Whatever Something de Paula',
email: '[email protected]',
}
};
environment.prod.ts
export const environment = {
production: true,
};
KeycloakService
클라이언트 측 에서 조롱하고 싶다면 Angular 종속성 주입에이를 처리하도록 지시 할 수 있습니다.
app.module.ts
import { environment } from '../environments/environment';
import { KeycloakService, KeycloakAngularModule } from 'keycloak-angular';
import { MockedKeycloakService } from './mocked-keycloak.service';
@NgModule({
...
imports: [
...
KeycloakAngularModule
],
providers: [
{
provide: KeycloakService,
useClass: environment.production ? KeycloakService : MockedKeycloakService
},
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
mocked-keycloak.service.ts
import { Injectable} from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
@Injectable()
class MockedKeycloakService extends KeycloakService {
init() {
return Promise.resolve(true);
}
getKeycloakInstance() {
return {
loadUserInfo: () => {
let callback;
Promise.resolve().then(() => {
callback({
userName: 'name'
});
});
return {
success: (fn) => callback = fn
};
}
} as any;
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다