Integrating Active Federation

Integrating Active Federation

Active federation involves contacting the Active Directory Federation Services (AD FS) web services endpoints. You need to obtain an AD username and password pair from your app user before you can use active federation. The Backend Services iOS SDK implements active federation through a single method, but it also features a few other methods that help you implement the active federation workflow yourself.

Prerequisites

You need to make certain settings before you can successfully log in your app users through AD FS.

Automatic Implementation

The Backend Services iOS SDK provides a method that implements the entire active federation workflow—from discovering your AD FS WS-Trust 1.3 endpoint to requesting and verifying the SAML token to authenticating the user with Telerik Platform.

On first invocation, Telerik Platform registers the user. Consequent invocations for the same user authenticate the user.

With active federation, you need to obtain an AD username and password pair from the app user by showing a user interface form. This is sensitive information that never reaches Telerik Platform. Then pass the collected credentials to the loginWithAdfs() method overload that accepts username and password.

[EVUser loginWithAdfs:username password:password block:^(EVUser *user, NSError *error) {
    //here in case of successful login the user object will have the isAuthenticated property set to true.
}

On success, the method returns an EVUser object initialized with an access token which will be used when invoking other APIs of the SDK. In that, the method behaves similarly to the Login() method.

Manual Implementation

The Backend Services iOS SDK offers a few other methods that help you implement active federation yourself. However, you still need to implement code that obtains the AD FS SAML token.

Obtaining a SAML Token

You need to obtain a SAML security token from the Active Directory Federation Services (AD FS) Security Token Service (STS) before calling the Backend Services iOS SDK method for registration/authentication.

To make the following web services calls, you need the AD FS metadata that you configured in Enabling Active Directory Federation Services Integration.

The following code is not part of the SDK neither uses it. It illustrates one of the many ways to obtain an AD FS security token. It is not secure by itself. You should take additional steps to ensure transport level security and message level security (e.g. HTTPS, encryption, signing, and so on).

+(void)obtainAdfsTokenWithSoapMessage:(NSString*) soapMessage metadataUrl:(NSString*) metaDataUrl block:(void (^)(NSString* token,NSError *error))block{

    //Substitute the URL of your STS endpoint found in the AD FS metadata document
    NSString *urlString = @"https://example.com/adfs/services/trust/13/UsernameMixed";
    NSURL *url = [NSURL URLWithString:urlString];

    NSMutableURLRequest  *urlRequest = [NSMutableURLRequest requestWithURL:url];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [urlRequest addValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [urlRequest setHTTPMethod:@"POST"];

    NSData *postData = [soapMessage dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    [urlRequest setHTTPBody:postData];
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
        if(error == nil){
            NSString* adfsToken = [data stringWithBase64Encode];
            block(adfsToken,nil);
        }
        else{
            block(nil,error);
        }

    }];
}

The soapMessage parameter must be a valid Request Security Token (RST) message. The code bellow shows how to build one using an XML template. The realm parameter must match AD FS realm that you configured in your app User settings.

+(NSString*) prepareSoapMessage:(NSString*) metadataUrl realm:(NSString*)realm username:(NSString*) username password:(NSString*) password{
    NSString *urlString = [metadataUrl stringByReplacingOccurrencesOfString:@"federationmetadata/2007-06/federationmetadata.xml" withString:@"adfs/services/trust/13/UsernameMixed"];

    NSString *soapMessage = kAdfsSoapMessageTemplate;
    soapMessage = [soapMessage stringByReplacingOccurrencesOfString:@"{url}" withString:urlString];
    soapMessage = [soapMessage stringByReplacingOccurrencesOfString:@"{realm}" withString:realm];
    soapMessage = [soapMessage stringByReplacingOccurrencesOfString:@"{username}" withString:username];
    soapMessage = [soapMessage stringByReplacingOccurrencesOfString:@"{password}" withString:password];

    return soapMessage;
}

The code uses the following XML template:

NSString* const kAdfsSoapMessageTemplate = @"<s:Envelope xmlns:s=\ "http://www.w3.org/2003/05/soap-envelope\" \ xmlns:a=\ "http://www.w3.org/2005/08/addressing\" \ xmlns:u=\ "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">\
    <s:Header>\
        <a:Action s:mustUnderstand=\ "1\">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>\
        <a:To s:mustUnderstand=\ "1\">{url}</a:To>\
        <o:Security s:mustUnderstand=\ "1\" xmlns:o=\ "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\
            <o:UsernameToken u:Id=\ "uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1\">\
                <o:Username>{username}</o:Username>\
                <o:Password Type=\ "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">{password}</o:Password>\
            </o:UsernameToken>\
        </o:Security>\
    </s:Header>\
    <s:Body>\
        <trust:RequestSecurityToken xmlns:trust=\ "http://docs.oasis-open.org/ws-sx/ws-trust/200512\">\
            <wsp:AppliesTo xmlns:wsp=\ "http://schemas.xmlsoap.org/ws/2004/09/policy\">\
                <a:EndpointReference>\
                    <a:Address>{realm}</a:Address>\
                </a:EndpointReference>\
            </wsp:AppliesTo>\
            <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>\
            <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>\
            <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>\
        </trust:RequestSecurityToken>\
    </s:Body>\
</s:Envelope>";
}

Registering or Authenticating a User

After you obtain an SAML token from the AD FS STS, you can use the loginWithAdfs() method overload that accepts a Base64-encoded token.

On first invocation, loginWithAdfs registers the user. Consequent invocations for the same user authenticate the user.

On success, the method returns an object containing a Telerik Platform access token (not to be mistaken with the AD FS SAML security token) that can be used with further Backend Services iOS SDK operations. In that, the loginWithAdfs() method behaves similarly to the login() method.

[EVUser loginWithAdfs:token block:^(EVUser *user, NSError *error) {
    //in case of successful login the user object has isAuthenticated=true
}

See Also

External resources:

Start a free trial Request a demo
Contact us: +1-888-365-2779
sales@telerik.com
Copyright © 2016-2017, Progress Software Corporation and/or its subsidiaries or affiliates. All rights reserved.