| Differences between
and this patch
- a/Source/WebKit/ChangeLog +26 lines
Lines 1-3 a/Source/WebKit/ChangeLog_sec1
1
2020-12-11  Jiewen Tan  <jiewen_tan@apple.com>
2
3
        [WebAuthn] Adopt new UI for the Security Key getAssertion flow
4
        https://bugs.webkit.org/show_bug.cgi?id=219711
5
        <rdar://problem/72154840>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        This patch adopts the new UI for the security key getAssertion flow which contains two part:
10
        1. showing a informative UI to ask the user to connect their security keys,
11
        2. showing an account picker for users to select a credential to use.
12
13
        Covered by manual tests.
14
15
        * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
16
        Paperwork.
17
18
        * UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h:
19
        * UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm:
20
        (WebKit::AuthenticatorPresenterCoordinator::AuthenticatorPresenterCoordinator):
21
        (WebKit::AuthenticatorPresenterCoordinator::selectAssertionResponse):
22
        (WebKit::AuthenticatorPresenterCoordinator::didSelectAssertionResponse):
23
        * UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm:
24
        (-[WKASCAuthorizationPresenterDelegate authorizationPresenter:credentialRequestedForLoginChoice:authenticatedContext:completionHandler:]):
25
        Implements the two flows.
26
1
2020-12-11  Brent Fulgham  <bfulgham@apple.com>
27
2020-12-11  Brent Fulgham  <bfulgham@apple.com>
2
28
3
        Expose API for enabling/disabling Private Click Measurement
29
        Expose API for enabling/disabling Private Click Measurement
- a/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h -5 / +13 lines
Lines 69-74 NS_ASSUME_NONNULL_BEGIN a/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h_sec1
69
@interface ASCAuthorizationPresenter : NSObject <ASCAuthorizationPresenterHostProtocol>
69
@interface ASCAuthorizationPresenter : NSObject <ASCAuthorizationPresenterHostProtocol>
70
70
71
- (void)presentAuthorizationWithContext:(ASCAuthorizationPresentationContext *)context completionHandler:(void (^)(id<ASCCredentialProtocol> _Nullable, NSError * _Nullable))completionHandler;
71
- (void)presentAuthorizationWithContext:(ASCAuthorizationPresentationContext *)context completionHandler:(void (^)(id<ASCCredentialProtocol> _Nullable, NSError * _Nullable))completionHandler;
72
- (void)updateInterfaceWithLoginChoices:(NSArray<id <ASCLoginChoiceProtocol>> *)loginChoices;
72
73
73
@property (nonatomic, weak) id <ASCAuthorizationPresenterDelegate> delegate;
74
@property (nonatomic, weak) id <ASCAuthorizationPresenterDelegate> delegate;
74
75
Lines 89-95 extern NSString * const ASCAuthorizationPresentationContextDataKey; a/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h_sec2
89
90
90
@property (nonatomic, readonly, copy) NSString *appIdentifier;
91
@property (nonatomic, readonly, copy) NSString *appIdentifier;
91
@property (nonatomic, readonly, copy) NSArray<id<ASCLoginChoiceProtocol>> *loginChoices;
92
@property (nonatomic, readonly, copy) NSArray<id<ASCLoginChoiceProtocol>> *loginChoices;
92
@property (nonatomic, nullable, copy) NSString *relyingPartyIdentifier;
93
@property (nonatomic, nullable, copy) NSString *serviceName;
93
94
94
@property (nonatomic, copy) NSString *proxiedAppName;
95
@property (nonatomic, copy) NSString *proxiedAppName;
95
@property (nonatomic, copy) NSArray<NSString *> *proxiedAssociatedDomains;
96
@property (nonatomic, copy) NSArray<NSString *> *proxiedAssociatedDomains;
Lines 102-116 extern NSString * const ASCAuthorizationPresentationContextDataKey; a/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h_sec3
102
103
103
@end
104
@end
104
105
106
typedef NS_ENUM(NSInteger, ASCSecurityKeyPublicKeyCredentialLoginChoiceKind) {
107
    ASCSecurityKeyPublicKeyCredentialLoginChoiceKindRegistration,
108
    ASCSecurityKeyPublicKeyCredentialLoginChoiceKindAssertion,
109
    ASCSecurityKeyPublicKeyCredentialLoginChoiceKindAssertionPlaceholder,
110
};
111
105
@interface ASCSecurityKeyPublicKeyCredentialLoginChoice : NSObject <ASCLoginChoiceProtocol>
112
@interface ASCSecurityKeyPublicKeyCredentialLoginChoice : NSObject <ASCLoginChoiceProtocol>
106
113
107
- (instancetype)initRegistrationChoice;
114
- (instancetype)initRegistrationChoice;
108
- (instancetype)initWithName:(NSString *)name displayName:(NSString *)displayName userHandle:(NSData *)userHandle;
115
- (instancetype)initWithName:(NSString *)name displayName:(NSString *)displayName userHandle:(NSData *)userHandle;
116
- (instancetype)initAssertionPlaceholderChoice;
109
117
110
@property (nonatomic, readonly, copy) NSString *name;
118
@property (nonatomic, nullable, readonly, copy) NSString *name;
111
@property (nonatomic, readonly, copy) NSString *displayName;
119
@property (nonatomic, nullable, readonly, copy) NSString *displayName;
112
@property (nonatomic, readonly, copy) NSData *userHandle;
120
@property (nonatomic, nullable, readonly, copy) NSData *userHandle;
113
@property (nonatomic, readonly) BOOL isRegistrationRequest;
121
@property (nonatomic, readonly) ASCSecurityKeyPublicKeyCredentialLoginChoiceKind loginChoiceKind;
114
122
115
+ (instancetype)new NS_UNAVAILABLE;
123
+ (instancetype)new NS_UNAVAILABLE;
116
- (instancetype)init NS_UNAVAILABLE;
124
- (instancetype)init NS_UNAVAILABLE;
- a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h +7 lines
Lines 28-33 a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h_sec1
28
#if ENABLE(WEB_AUTHN)
28
#if ENABLE(WEB_AUTHN)
29
29
30
#include "WebAuthenticationFlags.h"
30
#include "WebAuthenticationFlags.h"
31
#include <WebCore/AuthenticatorAssertionResponse.h>
31
#include <WebCore/AuthenticatorTransport.h>
32
#include <WebCore/AuthenticatorTransport.h>
32
#include <WebCore/WebAuthenticationConstants.h>
33
#include <WebCore/WebAuthenticationConstants.h>
33
#include <wtf/Forward.h>
34
#include <wtf/Forward.h>
Lines 35-40 a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h_sec2
35
#include <wtf/WeakPtr.h>
36
#include <wtf/WeakPtr.h>
36
37
37
OBJC_CLASS ASCAuthorizationPresenter;
38
OBJC_CLASS ASCAuthorizationPresenter;
39
OBJC_CLASS ASCLoginChoiceProtocol;
38
OBJC_CLASS LAContext;
40
OBJC_CLASS LAContext;
39
OBJC_CLASS WKASCAuthorizationPresenterDelegate;
41
OBJC_CLASS WKASCAuthorizationPresenterDelegate;
40
42
Lines 64-69 public: a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h_sec3
64
    void setCredentialRequestHandler(CredentialRequestHandler&& handler) { m_credentialRequestHandler = WTFMove(handler); }
66
    void setCredentialRequestHandler(CredentialRequestHandler&& handler) { m_credentialRequestHandler = WTFMove(handler); }
65
    void setLAContext(LAContext *);
67
    void setLAContext(LAContext *);
66
68
69
    void didSelectAssertionResponse(ASCLoginChoiceProtocol *);
70
67
private:
71
private:
68
    WeakPtr<AuthenticatorManager> m_manager;
72
    WeakPtr<AuthenticatorManager> m_manager;
69
    RetainPtr<ASCAuthorizationPresenter> m_presenter;
73
    RetainPtr<ASCAuthorizationPresenter> m_presenter;
Lines 73-78 private: a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.h_sec4
73
77
74
    CompletionHandler<void(LAContext *)> m_laContextHandler;
78
    CompletionHandler<void(LAContext *)> m_laContextHandler;
75
    RetainPtr<LAContext> m_laContext;
79
    RetainPtr<LAContext> m_laContext;
80
81
    CompletionHandler<void(WebCore::AuthenticatorAssertionResponse*)> m_responseHandler;
82
    HashMap<ASCLoginChoiceProtocol *, RefPtr<WebCore::AuthenticatorAssertionResponse>> m_credentials;
76
};
83
};
77
84
78
} // namespace WebKit
85
} // namespace WebKit
- a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm -6 / +36 lines
Lines 30-36 a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm_sec1
30
30
31
#import "AuthenticatorManager.h"
31
#import "AuthenticatorManager.h"
32
#import "WKASCAuthorizationPresenterDelegate.h"
32
#import "WKASCAuthorizationPresenterDelegate.h"
33
#import <WebCore/NotImplemented.h>
34
#import <wtf/BlockPtr.h>
33
#import <wtf/BlockPtr.h>
35
34
36
#import "AuthenticationServicesCoreSoftLink.h"
35
#import "AuthenticationServicesCoreSoftLink.h"
Lines 43-49 AuthenticatorPresenterCoordinator::AuthenticatorPresenterCoordinator(const Authe a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm_sec2
43
{
42
{
44
#if HAVE(ASC_AUTH_UI)
43
#if HAVE(ASC_AUTH_UI)
45
    auto presentationContext = adoptNS([allocASCAuthorizationPresentationContextInstance() initWithRequestContext:nullptr appIdentifier:nullptr]);
44
    auto presentationContext = adoptNS([allocASCAuthorizationPresentationContextInstance() initWithRequestContext:nullptr appIdentifier:nullptr]);
46
    [presentationContext setRelyingPartyIdentifier: rpId];
45
    [presentationContext setServiceName: rpId];
47
46
48
    switch (type) {
47
    switch (type) {
49
    case ClientDataType::Create:
48
    case ClientDataType::Create:
Lines 53-60 AuthenticatorPresenterCoordinator::AuthenticatorPresenterCoordinator(const Authe a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm_sec3
53
            [presentationContext addLoginChoice:adoptNS([allocASCSecurityKeyPublicKeyCredentialLoginChoiceInstance() initRegistrationChoice]).get()];
52
            [presentationContext addLoginChoice:adoptNS([allocASCSecurityKeyPublicKeyCredentialLoginChoiceInstance() initRegistrationChoice]).get()];
54
        break;
53
        break;
55
    case ClientDataType::Get:
54
    case ClientDataType::Get:
56
        // FIXME(219710): Adopt new UI for the Platform Authenticator getAssertion flow.
55
        if (transports.contains(AuthenticatorTransport::Usb) || transports.contains(AuthenticatorTransport::Nfc))
57
        // FIXME(219711): Adopt new UI for the Security Key getAssertion flow.
56
            [presentationContext addLoginChoice:adoptNS([allocASCSecurityKeyPublicKeyCredentialLoginChoiceInstance() initAssertionPlaceholderChoice]).get()];
58
        break;
57
        break;
59
    default:
58
    default:
60
        ASSERT_NOT_REACHED();
59
        ASSERT_NOT_REACHED();
Lines 90-99 void AuthenticatorPresenterCoordinator::requestPin(uint64_t, CompletionHandler<v a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm_sec4
90
    // FIXME(219712): Adopt new UI for the Client PIN flow.
89
    // FIXME(219712): Adopt new UI for the Client PIN flow.
91
}
90
}
92
91
93
void AuthenticatorPresenterCoordinator::selectAssertionResponse(Vector<Ref<AuthenticatorAssertionResponse>>&&, WebAuthenticationSource, CompletionHandler<void(AuthenticatorAssertionResponse*)>&&)
92
void AuthenticatorPresenterCoordinator::selectAssertionResponse(Vector<Ref<AuthenticatorAssertionResponse>>&& responses, WebAuthenticationSource source, CompletionHandler<void(AuthenticatorAssertionResponse*)>&& completionHandler)
94
{
93
{
94
#if HAVE(ASC_AUTH_UI)
95
    if (m_responseHandler)
96
        m_responseHandler(nullptr);
97
    m_responseHandler = WTFMove(completionHandler);
98
99
    if (source == WebAuthenticationSource::External) {
100
        auto loginChoices = adoptNS([[NSMutableArray alloc] init]);
101
102
        for (auto& response : responses) {
103
            RetainPtr<NSData> userHandle;
104
            if (response->userHandle())
105
                userHandle = adoptNS([[NSData alloc] initWithBytes:response->userHandle()->data() length:response->userHandle()->byteLength()]);
106
107
            auto loginChoice = adoptNS([allocASCSecurityKeyPublicKeyCredentialLoginChoiceInstance() initWithName:response->name() displayName:response->displayName() userHandle:userHandle.get()]);
108
            [loginChoices addObject:loginChoice.get()];
109
110
            m_credentials.add((ASCLoginChoiceProtocol *)loginChoice.get(), WTFMove(response));
111
        }
112
113
        [m_presenter updateInterfaceWithLoginChoices:loginChoices.get()];
114
        return;
115
    }
95
    // FIXME(219710): Adopt new UI for the Platform Authenticator getAssertion flow.
116
    // FIXME(219710): Adopt new UI for the Platform Authenticator getAssertion flow.
96
    // FIXME(219711): Adopt new UI for the Security Key getAssertion flow.
117
#endif // HAVE(ASC_AUTH_UI)
97
}
118
}
98
119
99
void AuthenticatorPresenterCoordinator::requestLAContextForUserVerification(CompletionHandler<void(LAContext *)>&& completionHandler)
120
void AuthenticatorPresenterCoordinator::requestLAContextForUserVerification(CompletionHandler<void(LAContext *)>&& completionHandler)
Lines 125-130 void AuthenticatorPresenterCoordinator::setLAContext(LAContext *context) a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/AuthenticatorPresenterCoordinator.mm_sec5
125
    m_laContext = context;
146
    m_laContext = context;
126
}
147
}
127
148
149
void AuthenticatorPresenterCoordinator::didSelectAssertionResponse(ASCLoginChoiceProtocol *loginChoice)
150
{
151
    auto response = m_credentials.take(loginChoice);
152
    if (!response)
153
        return;
154
155
    m_responseHandler(response.get());
156
}
157
128
} // namespace WebKit
158
} // namespace WebKit
129
159
130
#endif // ENABLE(WEB_AUTHN)
160
#endif // ENABLE(WEB_AUTHN)
- a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm +10 lines
Lines 65-70 - (void)authorizationPresenter:(ASCAuthorizationPresenter *)presenter credential a/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WKASCAuthorizationPresenterDelegate.mm_sec1
65
            return;
65
            return;
66
        }
66
        }
67
    }
67
    }
68
69
    if ([loginChoice isKindOfClass:WebKit::getASCSecurityKeyPublicKeyCredentialLoginChoiceClass()]) {
70
        if ([(ASCSecurityKeyPublicKeyCredentialLoginChoice *)loginChoice loginChoiceKind] == ASCSecurityKeyPublicKeyCredentialLoginChoiceKindAssertion) {
71
            [self dispatchCoordinatorCallback:[loginChoice] (WebKit::AuthenticatorPresenterCoordinator& coordinator) mutable {
72
                coordinator.didSelectAssertionResponse((ASCLoginChoiceProtocol *)loginChoice);
73
            }];
74
75
            return;
76
        }
77
    }
68
}
78
}
69
79
70
- (void)authorizationPresenter:(ASCAuthorizationPresenter *)presenter validateUserEnteredPIN:(NSString *)pin completionHandler:(void (^)(id <ASCCredentialProtocol> credential, NSError *error))completionHandler
80
- (void)authorizationPresenter:(ASCAuthorizationPresenter *)presenter validateUserEnteredPIN:(NSString *)pin completionHandler:(void (^)(id <ASCCredentialProtocol> credential, NSError *error))completionHandler

Return to Bug 219711