Newer Version Available
LoginDiscoveryHandler インターフェース
名前空間
使用方法
インタビューベースのログイン用の Auth.LoginDiscoveryHandler を実装します。このハンドラは、入力された ID からユーザを検索し、Site.passwordlessLogin をコールして、使用するログイン情報 (メール、SMS など) を決定できます。または、ハンドラはユーザをログイン用のサードパーティ ID プロバイダにリダイレクトできます。このハンドラを使用した場合、ログインページにパスワード項目は表示されません。ただし、Site.passwordlessLogin を使用して、パスワードを要求できます。
ユーザの観点では、ユーザはログイン画面で ID を入力します。次に、PIN またはパスワードを入力してログインを完了します。または、SSO が有効になっている場合、ユーザはログインをスキップします。
例については、「LoginDiscoveryHandler の実装例」を参照してください。詳細は、『Salesforce External Identity Implementation Guide (Salesforce External Identity 実装ガイド)』を参照してください。
LoginDiscoveryHandler メソッド
LoginDiscoveryHandler のメソッドは次のようになります。
LoginDiscoveryHandler の実装例
この Apex コード例は Auth.LoginDiscoveryHandler インターフェースを実装します。ログインページで提供された ID に応じて、ログインしているユーザのメールまたは電話番号が検証済みかどうかをチェックします。検証済みの場合 (Auth.VerificationMethod.EMAIL または Auth.VerificationMethod.SMS)、ID (ユーザのメールアドレスまたはモバイルデバイス) にチャレンジを送信します。検証ページでユーザがコードを正しく入力すると、ユーザは開始 URL で指定されたコミュニティページにリダイレクトされます。ユーザが検証されない場合、ユーザはログインのためのパスワードを入力する必要があります。
discoveryResult 関数は Site.passwordlessLogin メソッドをコールし、指定された検証方法でユーザをログインします。getSsoRedirect 関数は、ユーザが SAML または認証プロバイダを使用してログインする必要があるかどうかを参照します。実装に固有のロジックを追���して、この参照方法を操作します。
1global class AutocreatedDiscLoginHandler implements Auth.LoginDiscoveryHandler {
2
3global PageReference login(String identifier, String startUrl, Map<String, String> requestAttributes) {
4 if (identifier != null && isValidEmail(identifier)) {
5 // Search for user by email
6 List<User> users = [SELECT Id FROM User WHERE Email = :identifier AND IsActive = TRUE];
7 if (!users.isEmpty() && users.size() == 1) {
8 // User must have verified email before using this verification method. We cannot send message to unverified email.
9 // You can check if the user has email verified bit on and add the password verification method as fallback.
10 List<TwoFactorMethodsInfo> verifiedInfo = [SELECT HasUserVerifiedEmailAddress FROM TwoFactorMethodsInfo WHERE UserId = :users[0].Id];
11 if (!verifiedInfo.isEmpty() && verifiedInfo[0].HasUserVerifiedEmailAddress == true) {
12 // Use email verification method if the user's email is verified.
13 return discoveryResult(users[0], Auth.VerificationMethod.EMAIL, startUrl, null);
14 } else {
15 // Use password verification method as fallback if the user's email is unverified.
16 return discoveryResult(users[0], Auth.VerificationMethod.PASSWORD, startUrl, null);
17 }
18 } else {
19 throw new Auth.LoginDiscoveryException('No unique user found. User count=' + users.size());
20 }
21 }
22 if (identifier != null) {
23 String formattedSms = getFormattedSms(identifier);
24 if (formattedSms != null) {
25 // Search for user by SMS
26 List<User> users = [SELECT Id FROM User WHERE MobilePhone = :formattedSms AND IsActive = TRUE];
27 if (!users.isEmpty() && users.size() == 1) {
28 // User must have verified SMS before using this verification method. We cannot send message to unverified mobile number.
29 // You can check if the user has mobile verified bit on or add the password verification method as fallback.
30 List<TwoFactorMethodsInfo> verifiedInfo = [SELECT HasUserVerifiedMobileNumber FROM TwoFactorMethodsInfo WHERE UserId = :users[0].Id];
31 if (!verifiedInfo.isEmpty() && verifiedInfo[0].HasUserVerifiedMobileNumber == true) {
32 // Use SMS verification method if the user's mobile number is verified.
33 return discoveryResult(users[0], Auth.VerificationMethod.SMS, startUrl, null);
34 } else {
35 // Use password verification method as fallback if the user's mobile number is unverified.
36 return discoveryResult(users[0], Auth.VerificationMethod.PASSWORD, startUrl, null);
37 }
38 } else {
39 throw new Auth.LoginDiscoveryException('No unique user found. User count=' + users.size());
40 }
41 }
42 }
43 if (identifier != null) {
44 // You can customize the code to find user via other attributes, such as SSN or Federation ID
45 }
46 throw new Auth.LoginDiscoveryException('Invalid Identifier');
47}
48
49private boolean isValidEmail(String identifier) {
50 String emailRegex = '^[a-zA-Z0-9._|\\\\%#~`=?&/$^*!}{+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$';
51 // source: http://www.regular-expressions.info/email.html
52 Pattern EmailPattern = Pattern.compile(emailRegex);
53 Matcher EmailMatcher = EmailPattern.matcher(identifier);
54 if (EmailMatcher.matches()) { return true; }
55 else { return false; }
56}
57
58private String getFormattedSms(String identifier) {
59 // Accept SMS input formats with 1 or 2 digits country code, 3 digits area code and 7 digits number
60 // You can customize the SMS regex to allow different formats
61 String smsRegex = '^(\\+?\\d{1,2}?[\\s-])?(\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4})$';
62 Pattern smsPattern = Pattern.compile(smsRegex);
63 Matcher smsMatcher = SmsPattern.matcher(identifier);
64 if (smsMatcher.matches()) {
65 try {
66 // Format user input into the verified SMS format '+xx xxxxxxxxxx' before DB lookup
67 // Append US country code +1 by default if no country code is provided
68 String countryCode = smsMatcher.group(1) == null ? '+1' : smsMatcher.group(1);
69 return System.UserManagement.formatPhoneNumber(countryCode, smsMatcher.group(2));
70 } catch(System.InvalidParameterValueException e) {
71 return null;
72 }
73 } else { return null; }
74}
75
76private PageReference getSsoRedirect(User user, String startUrl, Map<String, String> requestAttributes) {
77 // You can look up if the user should log in with SAML or an Auth Provider and return the URL to initialize SSO.
78 return null;
79}
80
81private PageReference discoveryResult(User user, Auth.VerificationMethod method, String startUrl, Map<String, String> requestAttributes) {
82 PageReference ssoRedirect = getSsoRedirect(user, startUrl, requestAttributes);
83 if (ssoRedirect != null) {
84 return ssoRedirect;
85 } else {
86 if (method != null) {
87 List<Auth.VerificationMethod> methods = new List<Auth.VerificationMethod>();
88 methods.add(method);
89 PageReference pwdlessRedirect = Site.passwordlessLogin(user.Id, methods, startUrl);
90 if (pwdlessRedirect != null) {
91 return pwdlessRedirect;
92 } else {
93 throw new Auth.LoginDiscoveryException('No Passwordless Login redirect URL returned for verification method: ' + method);
94 }
95 } else {
96 throw new Auth.LoginDiscoveryException('No method found');
97 }
98 }
99}
100}