Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ - (void)doClientRegistration:(OIDServiceConfiguration *)configuration
grantTypes:nil
subjectType:nil
tokenEndpointAuthMethod:@"client_secret_post"
additionalParameters:nil];
additionalParameters:nil
additionalHeaders:nil];
// performs registration request
[self logMessage:@"Initiating registration request"];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ - (void)doClientRegistration:(OIDServiceConfiguration *)configuration
grantTypes:nil
subjectType:nil
tokenEndpointAuthMethod:@"client_secret_post"
additionalParameters:nil];
additionalParameters:nil
additionalHeaders:nil];
// performs registration request
[self logMessage:@"Initiating registration request"];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ extension AppAuthExampleViewController {
grantTypes: nil,
subjectType: nil,
tokenEndpointAuthMethod: "client_secret_post",
additionalParameters: nil)
additionalParameters: nil,
additionalHeaders: nil)

// performs registration request
self.logMessage("Initiating registration request")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ - (void)performAuthorizationWithConfiguration:(OIDTVServiceConfiguration *)confi
clientId:kClientID
clientSecret:kClientSecret
scopes:@[ OIDScopeOpenID, OIDScopeProfile ]
additionalParameters:nil];
additionalParameters:nil
additionalHeaders:nil];

OIDTVAuthorizationInitialization initBlock =
^(OIDTVAuthorizationResponse *_Nullable response, NSError *_Nullable error) {
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,8 @@ OIDTVAuthorizationRequest *request =
clientId:kClientID
clientSecret:kClientSecret
scopes:@[ OIDScopeOpenID, OIDScopeProfile ]
additionalParameters:nil];
additionalParameters:nil
additionalHeaders:nil];

// performs authentication request
OIDTVAuthorizationInitialization initBlock =
Expand Down
31 changes: 31 additions & 0 deletions Source/AppAuthCore/OIDAuthState.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ typedef void (^OIDAuthStateAction)(NSString *_Nullable accessToken,
typedef void (^OIDAuthStateAuthorizationCallback)(OIDAuthState *_Nullable authState,
NSError *_Nullable error);

/*! @brief The exception thrown when a developer tries to create a refresh request from an
authorization request with no authorization code.
*/
static NSString *const kRefreshTokenRequestException =
@"Attempted to create a token refresh request from a token response with no refresh token.";

/*! @brief A convenience class that retains the auth state between @c OIDAuthorizationResponse%s
and @c OIDTokenResponse%s.
*/
Expand Down Expand Up @@ -267,6 +273,31 @@ typedef void (^OIDAuthStateAuthorizationCallback)(OIDAuthState *_Nullable authSt
- (nullable OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;

/*! @brief Creates a token request suitable for refreshing an access token.
@param additionalParameters Additional parameters for the token request.
@param additionalHeaders Additional headers for the token request.
@return A @c OIDTokenRequest suitable for using a refresh token to obtain a new access token.
@discussion After performing the refresh, call @c OIDAuthState.updateWithTokenResponse:error:
to update the authorization state based on the response. Rather than doing the token refresh
yourself, you should use @c OIDAuthState.performActionWithFreshTokens:.
@see https://tools.ietf.org/html/rfc6749#section-1.5
*/
- (nullable OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:
(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

/*! @brief Creates a token request suitable for refreshing an access token.
@param additionalHeaders Additional parameters for the token request.
@return A @c OIDTokenRequest suitable for using a refresh token to obtain a new access token.
@discussion After performing the refresh, call @c OIDAuthState.updateWithTokenResponse:error:
to update the authorization state based on the response. Rather than doing the token refresh
yourself, you should use @c OIDAuthState.performActionWithFreshTokens:.
@see https://tools.ietf.org/html/rfc6749#section-1.5
*/
- (nullable OIDTokenRequest *)tokenRefreshRequestWithAdditionalHeaders:
(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

@end

NS_ASSUME_NONNULL_END
51 changes: 43 additions & 8 deletions Source/AppAuthCore/OIDAuthState.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@
*/
static NSString *const kAuthorizationErrorKey = @"authorizationError";

/*! @brief The exception thrown when a developer tries to create a refresh request from an
authorization request with no authorization code.
*/
static NSString *const kRefreshTokenRequestException =
@"Attempted to create a token refresh request from a token response with no refresh token.";

/*! @brief Number of seconds the access token is refreshed before it actually expires.
*/
static const NSUInteger kExpiryTimeTolerance = 60;
Expand Down Expand Up @@ -427,7 +421,47 @@ - (OIDTokenRequest *)tokenRefreshRequest {
- (OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
(NSDictionary<NSString *, NSString *> *)additionalParameters {

// TODO: Add unit test to confirm exception is thrown when expected
if (!_refreshToken) {
[OIDErrorUtilities raiseException:kRefreshTokenRequestException];
}
return [[OIDTokenRequest alloc]
initWithConfiguration:_lastAuthorizationResponse.request.configuration
grantType:OIDGrantTypeRefreshToken
authorizationCode:nil
redirectURL:nil
clientID:_lastAuthorizationResponse.request.clientID
clientSecret:_lastAuthorizationResponse.request.clientSecret
scope:nil
refreshToken:_refreshToken
codeVerifier:nil
additionalParameters:additionalParameters
additionalHeaders:nil];
}

- (OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
(NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:
(NSDictionary<NSString *,NSString *> *)additionalHeaders {

if (!_refreshToken) {
[OIDErrorUtilities raiseException:kRefreshTokenRequestException];
}
return [[OIDTokenRequest alloc]
initWithConfiguration:_lastAuthorizationResponse.request.configuration
grantType:OIDGrantTypeRefreshToken
authorizationCode:nil
redirectURL:nil
clientID:_lastAuthorizationResponse.request.clientID
clientSecret:_lastAuthorizationResponse.request.clientSecret
scope:nil
refreshToken:_refreshToken
codeVerifier:nil
additionalParameters:additionalParameters
additionalHeaders:additionalHeaders];
}

- (OIDTokenRequest *)tokenRefreshRequestWithAdditionalHeaders:
(NSDictionary<NSString *, NSString *> *)additionalHeaders {

if (!_refreshToken) {
[OIDErrorUtilities raiseException:kRefreshTokenRequestException];
Expand All @@ -442,7 +476,8 @@ - (OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
scope:nil
refreshToken:_refreshToken
codeVerifier:nil
additionalParameters:additionalParameters];
additionalParameters:nil
additionalHeaders:additionalHeaders];
}

#pragma mark - Stateful Actions
Expand Down
4 changes: 3 additions & 1 deletion Source/AppAuthCore/OIDAuthorizationResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ NS_ASSUME_NONNULL_BEGIN
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
*/
- (nullable OIDTokenRequest *)tokenExchangeRequestWithAdditionalParameters:
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:
(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

@end

Expand Down
9 changes: 6 additions & 3 deletions Source/AppAuthCore/OIDAuthorizationResponse.m
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,13 @@ - (NSString *)description {
#pragma mark -

- (OIDTokenRequest *)tokenExchangeRequest {
return [self tokenExchangeRequestWithAdditionalParameters:nil];
return [self tokenExchangeRequestWithAdditionalParameters:nil additionalHeaders:nil];
}

- (OIDTokenRequest *)tokenExchangeRequestWithAdditionalParameters:
(NSDictionary<NSString *, NSString *> *)additionalParameters {
(NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:
(NSDictionary<NSString *, NSString *> *)additionalHeaders {
// TODO: add a unit test to confirm exception is thrown when expected and the request is created
// with the correct parameters.
if (!_authorizationCode) {
Expand All @@ -204,7 +206,8 @@ - (OIDTokenRequest *)tokenExchangeRequestWithAdditionalParameters:
scope:nil
refreshToken:nil
codeVerifier:_request.codeVerifier
additionalParameters:additionalParameters];
additionalParameters:additionalParameters
additionalHeaders:additionalHeaders];
}

@end
12 changes: 10 additions & 2 deletions Source/AppAuthCore/OIDTokenRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalParameters;

/*! @brief The client's additional token request headers.
*/
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalHeaders;

/*! @internal
@brief Unavailable. Please use
initWithConfiguration:grantType:code:redirectURL:clientID:additionalParameters:.
initWithConfiguration:grantType:code:redirectURL:clientID:additionalParameters:additionalHeaders:.
*/
- (instancetype)init NS_UNAVAILABLE;

Expand All @@ -113,6 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
@param refreshToken The refresh token.
@param codeVerifier The PKCE code verifier.
@param additionalParameters The client's additional token request parameters.
@param additionalHeaders The client's additional token request headers.
*/
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
grantType:(NSString *)grantType
Expand All @@ -123,7 +128,8 @@ NS_ASSUME_NONNULL_BEGIN
scopes:(nullable NSArray<NSString *> *)scopes
refreshToken:(nullable NSString *)refreshToken
codeVerifier:(nullable NSString *)codeVerifier
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

/*! @brief Designated initializer.
@param configuration The service's configuration.
Expand All @@ -139,6 +145,7 @@ NS_ASSUME_NONNULL_BEGIN
@param refreshToken The refresh token.
@param codeVerifier The PKCE code verifier.
@param additionalParameters The client's additional token request parameters.
@param additionalHeaders The client's additional token request headers.
*/
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
grantType:(NSString *)grantType
Expand All @@ -150,6 +157,7 @@ NS_ASSUME_NONNULL_BEGIN
refreshToken:(nullable NSString *)refreshToken
codeVerifier:(nullable NSString *)codeVerifier
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders
NS_DESIGNATED_INITIALIZER;

/*! @brief Designated initializer for NSSecureCoding.
Expand Down
39 changes: 33 additions & 6 deletions Source/AppAuthCore/OIDTokenRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
*/
static NSString *const kAdditionalParametersKey = @"additionalParameters";

/*! @brief Key used to encode the @c additionalHeaders property for
@c NSSecureCoding
*/
static NSString *const kAdditionalHeadersKey = @"additionalHeaders";

@implementation OIDTokenRequest

- (instancetype)init
Expand All @@ -80,7 +85,8 @@ - (instancetype)init
scope:
refreshToken:
codeVerifier:
additionalParameters:)
additionalParameters:
additionalHeaders:)
)

- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
Expand All @@ -92,7 +98,8 @@ - (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
scopes:(nullable NSArray<NSString *> *)scopes
refreshToken:(nullable NSString *)refreshToken
codeVerifier:(nullable NSString *)codeVerifier
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders {
return [self initWithConfiguration:configuration
grantType:grantType
authorizationCode:code
Expand All @@ -102,7 +109,8 @@ - (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
scope:[OIDScopeUtilities scopesWithArray:scopes]
refreshToken:refreshToken
codeVerifier:(NSString *)codeVerifier
additionalParameters:additionalParameters];
additionalParameters:additionalParameters
additionalHeaders:additionalHeaders];
}

- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
Expand All @@ -114,7 +122,8 @@ - (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
scope:(nullable NSString *)scope
refreshToken:(nullable NSString *)refreshToken
codeVerifier:(nullable NSString *)codeVerifier
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders {
self = [super init];
if (self) {
_configuration = [configuration copy];
Expand All @@ -128,6 +137,8 @@ - (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
_codeVerifier = [codeVerifier copy];
_additionalParameters =
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
_additionalHeaders =
[[NSDictionary alloc] initWithDictionary:additionalHeaders copyItems:YES];

// Additional validation for the authorization_code grant type
if ([_grantType isEqual:OIDGrantTypeAuthorizationCode]) {
Expand Down Expand Up @@ -174,9 +185,18 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder {
[NSDictionary class],
[NSString class]
]];

NSDictionary *additionalParameters =
[aDecoder decodeObjectOfClasses:additionalParameterCodingClasses
forKey:kAdditionalParametersKey];
[aDecoder decodeObjectOfClasses:additionalParameterCodingClasses forKey:kAdditionalParametersKey];


NSSet *additionalHeaderCodingClasses = [NSSet setWithArray:@[
[NSDictionary class],
[NSString class]
]];

NSDictionary *additionalHeaders =
[aDecoder decodeObjectOfClasses:additionalHeaderCodingClasses forKey:kAdditionalHeadersKey];

self = [super init];
if (self) {
Expand All @@ -191,6 +211,8 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder {
_codeVerifier = [codeVerifier copy];
_additionalParameters =
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
_additionalHeaders =
[[NSDictionary alloc] initWithDictionary:additionalHeaders copyItems:YES];
}
return self;
}
Expand All @@ -206,6 +228,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_refreshToken forKey:kRefreshTokenKey];
[aCoder encodeObject:_codeVerifier forKey:kCodeVerifierKey];
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
[aCoder encodeObject:_additionalHeaders forKey:kAdditionalHeadersKey];
}

#pragma mark - NSObject overrides
Expand Down Expand Up @@ -305,6 +328,10 @@ - (NSURLRequest *)URLRequest {
for (id header in httpHeaders) {
[URLRequest setValue:httpHeaders[header] forHTTPHeaderField:header];
}

for (id header in _additionalHeaders) {
[URLRequest setValue:httpHeaders[header] forHTTPHeaderField:header];
}

return URLRequest;
}
Expand Down
19 changes: 19 additions & 0 deletions Source/AppAuthTV/OIDTVAuthorizationResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable OIDTVTokenRequest *)tokenPollRequestWithAdditionalParameters:
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;

/*! @brief Creates a token request suitable for polling the token endpoint with the @c deviceCode.
@param additionalHeaders Additional headers for the token request.
@return A @c OIDTVTokenRequest suitable for polling the token endpoint.
@see https://tools.ietf.org/html/rfc8628#section-3.4
*/
- (nullable OIDTVTokenRequest *)tokenPollRequestWithAdditionalHeaders:
(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

/*! @brief Creates a token request suitable for polling the token endpoint with the @c deviceCode.
@param additionalParameters Additional parameters for the token request.
@param additionalHeaders Additional headers for the token request.
@return A @c OIDTVTokenRequest suitable for polling the token endpoint.
@see https://tools.ietf.org/html/rfc8628#section-3.4
*/
- (nullable OIDTVTokenRequest *)tokenPollRequestWithAdditionalParameters:
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
additionalHeaders:
(nullable NSDictionary<NSString *, NSString *> *)additionalHeaders;

@end

NS_ASSUME_NONNULL_END
Loading