Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure AD B2C getting oauthConnection Error: Bad Request

While trying to integrate Azure AD B2C, I am stuck with an error "oauthConnection Error: Bad Request". Following their given sample app it all works fine. But after integrating the same copy paste code from the working sample app, and trying to log in with Facebook or Google Plus, it throws an error! I am pretty sure that every credential that I used in the sample app is the same for my app. Any idea about this will be highly appreciated. Here is my code, AppDelegate.m

#import "AppData.h"
#import "NXOAuth2.h"
#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {


    [self setupOAuth2AccountStore];

    // Override point for customization after application launch.
    return YES;
}

- (void)setupOAuth2AccountStore {
    AppData *data = [AppData getInstance]; // The singleton we use to get the settings

    NSDictionary *customHeaders =
    [NSDictionary dictionaryWithObject:@"application/x-www-form-urlencoded"
                                forKey:@"Content-Type"];

    // Azure B2C needs
    // kNXOAuth2AccountStoreConfigurationAdditionalAuthenticationParameters for
    // sending policy to the server,
    // therefore we use -setConfiguration:forAccountType:
    NSDictionary *B2cConfigDict = @{
                                    kNXOAuth2AccountStoreConfigurationClientID : data.clientID,
                                    kNXOAuth2AccountStoreConfigurationSecret : data.clientSecret,
                                    kNXOAuth2AccountStoreConfigurationScope :
                                        [NSSet setWithObjects:@"openid", data.clientID, nil],
                                    kNXOAuth2AccountStoreConfigurationAuthorizeURL :
                                        [NSURL URLWithString:data.authURL],
                                    kNXOAuth2AccountStoreConfigurationTokenURL :
                                        [NSURL URLWithString:data.tokenURL],
                                    kNXOAuth2AccountStoreConfigurationRedirectURL :
                                        [NSURL URLWithString:data.bhh],
                                    kNXOAuth2AccountStoreConfigurationCustomHeaderFields : customHeaders,
                                    //      kNXOAuth2AccountStoreConfigurationAdditionalAuthenticationParameters:customAuthenticationParameters
                                    };

    [[NXOAuth2AccountStore sharedStore] setConfiguration:B2cConfigDict
                                          forAccountType:data.accountIdentifier];
}

LoginViewController.m

#import "AppData.h"
#import "LoginViewController.h"
#import "NXOAuth2.h"

@interface LoginViewController ()

@end

@implementation LoginViewController {

    NSURL *myLoadedUrl;
    bool isRequestBusy;
}

// Put variables here

- (void)viewDidLoad {
    [super viewDidLoad];

    // OAuth2 Code
    self.loginView.delegate = self;
    [self requestOAuth2Access];
    [self setupOAuth2AccountStore];
    NSURLCache *URLCache =
    [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
                                  diskCapacity:20 * 1024 * 1024
                                      diskPath:nil];
    [NSURLCache setSharedURLCache:URLCache];

}


- (void)resolveUsingUIWebView:(NSURL *)URL {
    // We get the auth token from a redirect so we need to handle that in the
    // webview.

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(resolveUsingUIWebView:)
                               withObject:URL
                            waitUntilDone:YES];
        return;
    }

    NSURLRequest *hostnameURLRequest =
    [NSURLRequest requestWithURL:URL
                     cachePolicy:NSURLRequestUseProtocolCachePolicy
                 timeoutInterval:10.0f];
    isRequestBusy = YES;
    [self.loginView loadRequest:hostnameURLRequest];

    NSLog(@"resolveUsingUIWebView ready (status: UNKNOWN, URL: %@)",
          self.loginView.request.URL);
}

- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType {
    AppData *data = [AppData getInstance];

    NSLog(@"webView:shouldStartLoadWithRequest: %@ (%li)", request.URL,
          (long)navigationType);

    // The webview is where all the communication happens. Slightly complicated.

    myLoadedUrl = [webView.request mainDocumentURL];
    NSLog(@"***Loaded url: %@", myLoadedUrl);

    // if the UIWebView is showing our authorization URL or consent URL, show the
    // UIWebView control
    if ([request.URL.absoluteString rangeOfString:data.authURL
                                          options:NSCaseInsensitiveSearch]
        .location != NSNotFound) {
        self.loginView.hidden = NO;
    } else if ([request.URL.absoluteString rangeOfString:data.loginURL
                                                 options:NSCaseInsensitiveSearch]
               .location != NSNotFound) {
        // otherwise hide the UIWebView, we've left the authorization flow
        self.loginView.hidden = NO;
    } else if ([request.URL.absoluteString rangeOfString:data.bhh
                                                 options:NSCaseInsensitiveSearch]
               .location != NSNotFound) {
        // otherwise hide the UIWebView, we've left the authorization flow
        self.loginView.hidden = YES;
        [[NXOAuth2AccountStore sharedStore] handleRedirectURL:request.URL];
    } else {
        self.loginView.hidden = NO;

    }

    return YES;
}







#pragma mark - UIWebViewDelegate methods
- (void)webViewDidFinishLoad:(UIWebView *)webView {
  // The webview is where all the communication happens. Slightly complicated.
}
- (void)handleOAuth2AccessResult:(NSURL *)accessResult {
    // parse the response for success or failure
    if (accessResult)
        // if success, complete the OAuth2 flow by handling the redirect URL and
        // obtaining a token
    {
        [[NXOAuth2AccountStore sharedStore] handleRedirectURL:accessResult];
    } else {
        // start over
        [self requestOAuth2Access];
    }
}
- (void)setupOAuth2AccountStore {
    [[NSNotificationCenter defaultCenter]
     addObserverForName:NXOAuth2AccountStoreAccountsDidChangeNotification
     object:[NXOAuth2AccountStore sharedStore]
     queue:nil
     usingBlock:^(NSNotification *aNotification) {
         if (aNotification.userInfo) {
             // account added, we have access
             // we can now request protected data
             NSLog(@"Success!! We have an access token.");
         } else {
             // account removed, we lost access
         }
     }];

    [[NSNotificationCenter defaultCenter]
     addObserverForName:NXOAuth2AccountStoreDidFailToRequestAccessNotification
     object:[NXOAuth2AccountStore sharedStore]
     queue:nil
     usingBlock:^(NSNotification *aNotification) {
         NSError *error = [aNotification.userInfo
                           objectForKey:NXOAuth2AccountStoreErrorKey];

        // Always got stuck here while trying to login with any credentials
         NSLog(@"Error!! %@", error.localizedDescription);
     }];
}


- (void)requestOAuth2Access {
    AppData *data = [AppData getInstance];

    [[NXOAuth2AccountStore sharedStore]
     requestAccessToAccountWithType:data.accountIdentifier
     withPreparedAuthorizationURLHandler:^(NSURL *preparedURL) {

         NSURLRequest *r = [NSURLRequest requestWithURL:preparedURL];
         [self.loginView loadRequest:r];
     }];
}

ViewController.m

#import "ViewController.h"
#import "AppData.h"
#import "LoginViewController.h"
#import "NXOAuth2.h"
// Login Action
    - (IBAction)login:(id)sender {
        LoginViewController *userSelectController =
        [self.storyboard instantiateViewControllerWithIdentifier:@"login"];
        [self.navigationController pushViewController:userSelectController
                                             animated:YES];
    }
like image 305
Vashum Avatar asked Oct 29 '22 17:10

Vashum


1 Answers

In case if anybody stumbles in this, Here is the solution

Go to pod, NXOAuth2Client.m and replace the method - (void)requestTokenWithAuthGrant:(NSString *)authGrant redirectURL:(NSURL *)redirectURL; with the below code

- (void)requestTokenWithAuthGrant:(NSString *)authGrant redirectURL:(NSURL *)redirectURL;
{
    NSAssert1(!authConnection, @"authConnection already running with: %@", authConnection);

    NSMutableURLRequest *tokenRequest = [NSMutableURLRequest requestWithURL:tokenURL];
    [tokenRequest setHTTPMethod:self.tokenRequestHTTPMethod];
    [authConnection cancel];  // just to be sure

    self.authenticating = YES;

    NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       @"authorization_code", @"grant_type",
                                       clientId, @"client_id",
                                      // clientSecret, @"client_secret",
                                       [redirectURL absoluteString], @"redirect_uri",
                                       authGrant, @"code",
                                       nil];
    if (self.desiredScope) {
        [parameters setObject:[[self.desiredScope allObjects] componentsJoinedByString:@" "] forKey:@"scope"];
    }

    if (self.customHeaderFields) {
        [self.customHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
            [tokenRequest addValue:obj forHTTPHeaderField:key];
        }];
    }

    if (self.additionalAuthenticationParameters) {
        [parameters addEntriesFromDictionary:self.additionalAuthenticationParameters];
    }

    authConnection = [[NXOAuth2Connection alloc] initWithRequest:tokenRequest
                                               requestParameters:parameters
                                                     oauthClient:self
                                                        delegate:self];
    authConnection.context = NXOAuth2ClientConnectionContextTokenRequest;
}

Commenting clientSecret solved the issue

like image 192
Vashum Avatar answered Nov 09 '22 05:11

Vashum