1) Apex (Authenticator 강제 해제)
// 파일명: MfaDisconnectActionAura.cls
public with sharing class MfaDisconnectActionAura {
@AuraEnabled
public static String disconnect(Id userId){
try {
System.UserManagement.deregisterVerificationMethod(
userId,
Auth.VerificationMethod.SALESFORCE_AUTHENTICATOR
);
return 'Salesforce Authenticator 연결을 해제했습니다.';
} catch (Exception e) {
// 메시지 노출용
throw new AuraHandledException('해제 실패: ' + e.getMessage());
}
}
}
2) Aura 컴포넌트 (버튼 + 컨펌 + 스피너 + 토스트)
.cmp
<!-- 파일명: mfaDisconnectQuickAction.cmp -->
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction"
access="global">
<aura:attribute name="recordId" type="Id"/>
<aura:attribute name="isBusy" type="Boolean" default="false"/>
<lightning:card title="Salesforce Authenticator Disconnect">
<aura:set attribute="actions">
<lightning:button variant="brand"
label="Disconnect"
onclick="{!c.onClickDisconnect}"
disabled="{!v.isBusy}"/>
</aura:set>
<aura:if isTrue="{!v.isBusy}">
<lightning:spinner alternativeText="Processing..." size="small"/>
</aura:if>
<div class="slds-p-around_small slds-text-color_weak">
사용자(Auth App) 연결을 끊고 새 폰에 재등록할 수 있게 합니다.
</div>
</lightning:card>
</aura:component>
Controller.js
// 파일명: mfaDisconnectQuickActionController.js
({
onClickDisconnect : function(cmp, evt, hlp) {
// 간단한 컨펌창 (브라우저 기본 confirm)
if (confirm('해당 사용자의 Salesforce Authenticator 연결을 해제하시겠습니까?')) {
hlp.disconnect(cmp);
}
}
})
Helper.js
// 파일명: mfaDisconnectQuickActionHelper.js
({
disconnect : function(cmp){
cmp.set("v.isBusy", true);
var action = cmp.get("c.disconnect");
action.setParams({ userId : cmp.get("v.recordId") });
action.setCallback(this, function(resp){
cmp.set("v.isBusy", false);
var state = resp.getState();
if (state === "SUCCESS") {
this.toast('성공', resp.getReturnValue(), 'success');
// 퀵액션 닫기 + 화면 새로고침(선택)
$A.get("e.force:closeQuickAction").fire();
$A.get("e.force:refreshView").fire();
} else {
var msg = '해제 실패';
try {
msg += ': ' + resp.getError()[0].message;
} catch(e){}
this.toast('오류', msg, 'error');
}
});
$A.enqueueAction(action);
},
toast : function(title, message, type){
var evt = $A.get("e.force:showToast");
if (evt) {
evt.setParams({ title: title, message: message, type: type, mode: 'dismissible' });
evt.fire();
} else {
alert(title + ' - ' + message);
}
}
})
.design (레코드 페이지에 올릴 수 있게)
<!-- 파일명: mfaDisconnectQuickAction.design -->
<design:component label="MFA Disconnect Quick Action"/>
3) 배치 방법
- 위 4개 파일 배포(Apex + Aura 3종).
- User 객체 레코드 페이지에서
- 퀵액션으로 쓰기: Setup → Object Manager → User → Buttons, Links, and Actions → New Action → (Aura는 Record Action 등록 대신) App Builder에서 Record Page 열고 **“mfaDisconnectQuickAction”**를 Quick Actions 영역 또는 페이지 섹션에 끌어다 놓기.
- 권한: 호출 Apex 클래스 접근권한을 콜센터 전용 권한집합에 부여.
- 테스트: User 레코드에서 버튼 클릭 → 컨펌 “예” → 토스트 성공 → User 상세의 App Registration에서 Authenticator가 사라졌는지 확인.
4) 옵션(좀 더 세련된 컨펌 UI 원하면)
- lightning:overlayLibrary로 커스텀 모달을 띄워 “예/아니오” 버튼을 만들 수 있음. 하지만 빠르게는 위처럼 브라우저 confirm() 이 가장 단순하고 안정적.
- 또는 lightning:notificationsLibrary.showNotice는 경고/에러용이라 “확인/취소” 2버튼 컨펌에는 적합하지 않음. 커스텀 모달을 권장.
5) 운영 팁
- 감사 로깅이 필요하면 Helper에서 성공 시
MFA_Disconnect__c커스텀 객체에 레코드 생성(대상자/실행자/시각/사유). - 접근 통제: 콜센터 권한집합만 이 컴포넌트가 보이도록 페이지 가시성 조건(권한 기반) 설정.
- SSO 환경이면 IdP MFA는 별개이므로, 이 버튼은 Salesforce 측 등록만 끊음(정상 동작).