Skip to Content

Hello, back again with another blog in my and Joanna Chan’s series on building a Cloud based mobile application.

Last time I wrote about the fun I was having authenticating users to the SAP NetWeaver Cloud application without using the standard built in SAML authentication. Instead of the standard SAML, we were aiming to have a more consumer focused logon using Twitter, Facebook and Google. Well once that started to work, we were up to the next exciting phase of our adventure.

The next step

Somewhat unsurprisingly (if you know me) at the beginning of our build, Jo and I sketched out what is was we were going to do, and how we’d break that down into tasks.

Our_plan.jpg

It seems that in our Mobile App that uses the cloud – the cloud is clearly at the centre of everything! This is again somewhat unsurprising – adopting the use of the “cloud” is going to be a big advantage to businesses that make that step forward.

We needed to build a set of RESTful APIs (I’ll write about the challenges of that in another blog) in the cloud that the mobile device could use to get data from and send data to. But in order for those API calls to work, we needed somehow to authenticate our device with the cloud.

The challenges

When it comes to the whole area of application management, there are some key problems to overcome.

  1. How to securely authenticate your mobile device.
  2. How to deliver any password /secret key to the device.
  3. How to disable the device’s access to the system in the event that device is compromised/lost.
  4. Make all of that as easy and painless as possible.

I thought about this a fair bit (and to be honest am still thinking about it.) The video below talks through some of my thoughts.

Please note that SCN sizes the videos a fair bit smaller than they can be viewed – this vid for example was rendered and uploaded to YouTube at 640×480 (anamorphic) res so could happily be viewed at 860×480 res, but you’ll have to open it in another browser to see that! – user this link – http://www.youtube.com/embed/_HuyN_pyb6U

In a nutshell:

  • OAuth is cool, but just because you used something once doesn’t mean it’s right to do it again. One big problem in even attempting this was the lack of OAuth Provider libs
  • Mobile devices (well, many of them at least!) aren’t particularly big (the whole point of being mobile. Things that you can do easily on a desktop, aren’t so easy on device.
  • Entering passwords stinks.
  • Most/Many people have more than one mobile device now, phone, tablet, business phone,
  • Public/Private key schemes are cool, but don’t solve the problem of distribution/identification.
  • Device management is overkill, and something that consumers will not accept.
  • Your employees are the consumers of your HR systems.
  • Why should employees accept what a consumer wouldn’t?
  • If you are using HTTPS for all your communications then your comms are already pretty damn secure  – sending your password unencrypted (Basic Auth) isn’t a problem.
  • By using “out of band” communications to transmit logon details, we increase the security.
  • By combining the login authentication with the application management views it is very transparent to the end user what is happening
  • Wish list: I’d use a QR Code to transmit the pairing and verification codes so user doesn’t have to type them in.
  • Wish list: I’d use web sockets to immediately update the admin tables! But my refresh button isn’t too bad…

In the end we built something which is pretty similar (in functionality) to the SuccessFactors application authentication (video linked) – but I think looks nicer 🙂 I also think that by going from cloud to device rather than device to cloud, we have future options around things like using QR Codes which would be hard the other way around.

Device Management

On successful sign in to the application (web page) using OAuth you can go to the device management page:

Device management page.png

Here you can add a new device by pressing on the nicely styled (using JQueryUI ThemeRoller) add device button:

new device added.png

Quick aside about some awesome jQuery plug-ins

As a quick deviation from the main flow/topic (as was so poetically said by my friend and fellow SAP Mentor Prashanth):

I’ve seen where SAPUI5 is going, and it impresses the hell out of me that such a team is putting together some really great stuff. But I’m even more impressed (sorry SAPUI5 team) with what is generally available out there anyway. For example, I was able to theme the buttons and the table that I’m using without having to do any serious CSS manipulation myself. I just used ThemeRoller to build a theme that matched my company’s colours and then it was automagically picked up by the jQuery plug-in table API I used (DataTables). And obviously the jQueryUI buttons I used picked up the theme. But the next bit I managed to find, was the icing on the cake… Clicking on the name of the device enables me to edit in-place and rename it. Pressing enter saves the update.

device name editable.png

Pretty awesome really! and pretty simple too – use the Jeditable plug-in for jQuery and then a few lines of code:

$(‘#deviceTable’).dataTable().$(‘td.editable’).editable(updateDeviceName, {

                “indicator” : ‘updating…’,

                “tooltip” : ‘Click to edit…’,

                “callback” : function(sValue, y) {

                        var deviceTable = $(‘#deviceTable’).dataTable();

                        var aPos = deviceTable.fnGetPosition(this);

                        deviceTable.fnUpdate(sValue, aPos[0], aPos[1]);

                },

                “submitdata” : function(value, settings) {

                        return {

                                “row_id” : this.parentNode.getAttribute(‘Id’),

                                “column” : $(‘#deviceTable’).dataTable().fnGetPosition(this)[2]

                        };

                },

                “height” : “14px”,

                “width” : “100%”

        });

The above sets the table element (previously given class of “editable”) to call the below function on pressing enter.

function updateDeviceName(value, settings) {

        var deviceTable = $(‘#deviceTable’).dataTable();

        var deviceURL = deviceTable.fnGetData(this.parentNode, 5);

        var blocked = deviceTable.fnGetData(this.parentNode, 3);

        var devices = {

                “Devices” : {

                        “DeviceName” : value,

                        “Blocked” : blocked,

                }

        };

        var devicesJson = JSON.stringify(devices);

        $.ajax({

                type : “PUT”,

                url : deviceURL,

                data : devicesJson,

                dataType : “json”,

                async : false

        }).fail(postErrorThrown);

        return (value);

}

A very simple function which takes values from current table line and then PUTs this update back into the resource that is the device.  Much more intuitive than having to select a table line so that it can be edited in some fields and pressing a submit button… 😉

Anyway back on track now 🙂

So once you’ve added your device on the web page, you can enter the pairing code into the mobile application.

iOS Simulator Screen shot 11.01.2013 4.52.30 PM.png

Once you’ve done that, the mobile app makes a call to a resource keyed by the pairing id. That API returns details about the device, including the user id it is associated with and the username and password that should be used for all subsequent communications from the device.

{

“Devices”: {

“Id”: 1,

“URL”: “http://chris.wombling.com:8080/DiscoveryTimesheetDemo/TimeSheetDevice/1“,

“AssociatedUser”: “http://chris.wombling.com:8080/DiscoveryTimesheetDemo/TimeSheetUsers/1“,

“AssociatedUserId”: 1,

“DeviceName”: “Chris Paine device”,

“PairingKey”: null,

“ValidationKey”: “179937”,

“PairedDate”: “16/01/2013”,

“Secret”: “cd81620a-349a-4745-9849-3eb2e4b84da6”,

“Blocked”: “N”

    }

}

At this point the device looses it’s pairing key – it is now paired. Any subsequent requests will return a 404 from the server. All further communication to the Cloud needs to be authenticated using the username (“AssociatedUserId”) and the password (“Secret”). In trying to keep in the spirit of RESTful services – all the other resources in my app are then discoverable from the one “AssociatedUser” URL.

paired device.png

Checking Basic Auth in NWCloud

Each REST API  that I have in my Cloud application calls some common authentication code to check that the user is valid. Firstly I check if there is a cookie to authorise the user (used by web interface). If the cookie doesn’t exist or validate, I then check for basic authentication. Here’s the code snippit which does the Basic Auth:

if (user == null) {

                // check if the authentication is instead being handled by basic

                // auth

                String authHeader = request.getHeader(“Authorization”);

                if (authHeader != null) {

                        logger.debug(“auth string found in header “ + authHeader);

                        // attempt to parse out the user id and password

                        String base64 = authHeader

                                        .substring(authHeader.indexOf(” “) + 1);

                        if (base64 != null) {

                                String decodedValue = Base64.base64Decode(base64);

                                logger.debug(“decoded value “ + decodedValue);

                                // split at “:”

                                String username = decodedValue.substring(0,

                                                decodedValue.indexOf(“:”));

                                String password = decodedValue.substring(decodedValue

                                                .indexOf(“:”) + 1);

                                if (username != null && password != null) {

                                        logger.debug(“decoded values username” + username

                                                        + ” password “ + password);

                                        int id = Integer.parseInt(username);

                                        TimeSheetMobileApp device = userData

                                                        .getDeviceFromId(id);

                                        if (device != null) {

                                                if (device.getBlocked().equals(“N”)) {

                                                        if (device.getSecret().equals(password)) {

                                                                user = device.getAssociatedUser();

                                                        }

                                                }

                                        }

                                }

                        }

                }

        }

        return user;

I realise there are issues with the code that will most likely cause it to crash if it’s supplied with anything other than what I expect it to be. But a few try/catch blocks should fix that (and make it much harder to read for the purposes of this blog…) (I’d also like to enhance the method to throw exceptions rather than just returning a null if the user isn’t authorised. <sigh> so much #TODO) But, my aim here isn’t perfection, but to show you what can be achieved!

Device management? No Sir! We’ll just cancel your credit card.

If you’re particularly into your code, you might have noticed that the above authentication routine checks to see if the device is marked as “blocked”.  On the same page where we added the device and found the pairing code, we have the option to lock each device. This stops the devices from being able to use their username and password that was assigned during pairing. The typical use case is where the user thinks that they might have lost their phone but isn’t sure.

cancel card.png

It’s like putting your credit card over limit, rather than cancelling it. Because, as someone who’s had their credit card cancelled due to a bank error, I can tell you it’s a great big pain having to go and change the numbers in all the places you use it. Having also been over limit a few times, it’s nice to know that it’s temporary and can be fixed, nevertheless it sure stops things working! That’s what our device management table allows – a simple way for users to stop the application working on a device and then re-enable it if needed. But they can also completely remove a device if required.

Of course, administrators can also do this on behalf of existing users (although I haven’t built the front end for that functionality yet!)

In summary

What we’ve put together is a very simple way that anyone could copy and use (and please do!) to authenticate and manage a very simple mobile application that uses SAP NWCloud.

What this isn’t is a way to manage devices and/or deploy and manage applications centrally. But instead a very simple and relatively secure solution for ensuring that those consumer type users can start benefiting from mobile apps.

I’m sure I’m touching on a few raw nerves here by not espousing SAP’s mobile device management technology in this area (especially after their new and better application management announcements late last year), but I think there is a place for these simple more consumer focused solutions, especially where the data concerned isn’t a worry if it’s exposed. That, and this is “FREE”!

Disclaimer, ramblings and what’s next

Again, I’d like to thank my wonderful employer for giving me the time to play with this tech, and to absolve them for the blame. These ramblings, thoughts, code errors, etc. are my own and in no way should be taken to be representative of my employer, unless they want it to. (And I didn’t stop to ask which bits they thought were representative, probably because I was up until 1:45am writing blogs like this.) I do write these blogs in the hope that someone will find them useful, so if you do (or don’t), please leave a comment, I’d love to know what you think. 🙂

Stay tuned for the next in the series, where Jo is going to do a tell-all exposé on the joys of mobile development and why she might be starting to like Android a bit more 😀 (or not, we’ll wait and see). I will also be writing about the fun I’ve had building RESTful APIs using JSON (not a speck of OData) in the cloud with SAP NWCloud and my thoughts (and painful learnings) about that.

To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Luke Marson

    Great job Chris and it’s interesting to see the complexity required when building apps. Security is paramount for Cloud and Mobility apps so it’s good to highlight what customers and partners need to do when considering building these type of HR apps.

    Best regards,

    Luke

    (0) 
    1. Chris Paine

      Thanks Luke,

      glad you liked it. It’s a step away from my usual HR functional work, but it is good to understand (I think) how things work at the nuts and bolts level in order to be able to advise people when it comes to how they should be building solutions and what tooling they might want to consider.

      The cloud space (and developing enhancements for both cloud-based and onPremise based solutions in it) is an area which few seem to understand well yet. My aim here is to try to understand it as well as possible myself, and hopefully share that knowledge with others too! 🙂

      (0) 
      1. Luke Marson

        HI Chris,

        I often like to step outside of my comfort zone and I’ve already done that in many of my endeavours this year (a kind of New Year’s resolution), particularly in cloud HCM.

        I absolutely agree that a technical understanding is required to fully serve a customer’s needs. I believe that every functional consultant should have a basic understanding of how things work from a technical perspective. And sharing is another quality 🙂

        Keep it up!

        Luke

        (0) 
  2. Frank Koehntopp

    Hi Chris,

    that sure looks neat!

    From a customer perspective I would recommend to make sure this works for your mobile strategy. Are all your mobile apps going to be provided inhouse or by the same partner? If not, how do you do device, app and user management over all of them?

    And the usual security comment: please make sure you don’t store the unencrypted password ANYWHERE on the server.See here: http://blog.mozilla.org/webdev/2012/06/08/lets-talk-about-password-storage/

    (0) 
    1. Chris Paine

      Frank, thanks for the comments and the reminder to fix my password storage!

      I’ve updated – in the code that sends the password to the device during pairing:

      String unhashedSecret = UUID.randomUUID().toString();

      String hashedSecret = BCrypt.hashpw(unhashedSecret, BCrypt.gensalt(12));

      device.setSecret(hashedSecret);

      userData.store(device);

      device.setSecret(unhashedSecret);

      DeviceJsonOutput.outputResponse(device, request, response, SERVLET_NAME);

      // as we need to send the unhashed version to the device when pairing

      and when checking the password:

      if (device != null) {

                if (device.getBlocked().equals(“N”)) {

                          if (BCrypt.checkpw(password, device.getSecret())) {

                                    user = device.getAssociatedUser();

                          }

                }

      }

      using JBCrypt – http://www.mindrot.org/projects/jBCrypt/

      I also agree, you really need to think about how you are going to manage your mobile strategy as an enterprise. Products like Afaria, can really help with that. But if you are looking for a more consumer focus (like rolling out an application that can help your business partners and other external customers, then this path is one that is quite useful.)

      Again, I should point out I took a reasonable amount of inspiration from the solution that SuccessFactors have used for their mobile app/device management solution. (just made it better 😉 )

      (0) 
  3. L. van Hengel

    Hi Chris,

    Very useful and thanks for sharing. Looking forward to your next blogs with all the ideas from your video like QR codes and WebSockets 🙂

    Your use of base64 in the example reminds me of my own #sapnwcloud application where i also store a base64 hash (server-side)  for communication to my NW7.3 BPM system. Note to myself  to blog about my experiences with NetWeaver Cloud as well 😉

    Cheers,

    Leo

    (0) 
    1. Chris Paine

      Hi Leo,

      Thanks, I’m glad you found it interesting and useful.

      before Frank jumps in 😉 . It’s worth mentioning that Base64 is just an encoding, not a hash – it doesn’t offer any security benefits! The security comes from using HTTPS whilst transmitting the basic authentication.

      I’d love to read a blog about your solution sometime, please do blog about it!

      Cheers,

      Chris

      (0) 
      1. L. van Hengel

        You are right. It’s encoding not hashing. I will also checkout the BCrypt library as well, better be safe even when storing in a session variable…

        Hopefully i’ll have my blog out soon, i am not the fastest blogger…. but already got lots of friendly reminders to blog about my experiences with #sapnwcloud 😉

        (0) 
  4. Harald Mueller

    Kudos for the great blog and the video. Did you consider to publish the source code on github? First #sapnwcloud samples are available https://github.com/sapnwcloud  and there is a lot more to come. We encourage everybody to fork, contribute and improve. Looking forward to your next thoughts and pain(e;-)ful learnings.

    BTW – UI5 is based on JQuery so it’s not an either/or but rather how does UI5 extend and complement JQuery.

    (0) 
    1. Chris Paine

      Hi Harald, as you can read in the next blog in the series – RESTful APIs in SAP NetWeaver Cloud with a mobile device we are already using GitHub. At the moment, the repository is private, we might reconsider that at a later point in time, it’s certainly something I’m thinking about.

      Re UI5 – I’ve had the discussion before, and am very impressed with what is being done – it’s just I’m more impressed with what has already been done outside of the SAP world. It’s a conversation for a dinner/bar sometime. 🙂 I certainly don’t want to belittle what UI5 does. But finding a table that I could edit in-line that easily matched my generated CSS theming was just too cool! 😎

      PS. glad you liked the blog – I’m finding the possibilities of SAP NW Cloud are pretty limitless!

      (0) 
      1. Chris Paine

        PPS – Harald you may like to know that one of your tweets features in the latest blog in the series. Thanks for pointing me at Liquibase, a very interesting solution to the problem. (That said I still want a “drop all db tables” button on the admin console 🙂 .)

        (0) 
        1. Chris Paine

          Robert, that’s cool!

          so when it the Themeroller support coming? 😉 (jesting aside, I heard that this is a real possibility for some similar theming support to be developed?) Or has it happened already?

          (0) 
          1. Robert Wetzold

            Multiple themes are already possible and can be switched at runtime! I’d recommend to check out the Theming FAQ in the UI5 Demo Kit and a method with the nice name setThemeRoot() 🙂 Also, you can build your own theme by modifying the theme parameters (look for them in the testsuite).

            (0) 
            1. Chris Paine

              Thanks Robert,

              But heard rumours of something that was as easy to use as ThemeRoller coming (playing with CSS directly and swapping between a limited set of themes isn’t quite as flexible as I’d like)??? Likely you can’t confirm or deny. But that’s cool.

              Anyway – what there is is still cool and I do like the Edding theme for demonstrating the power of CSS. Thanks for the details.

              (0) 

Leave a Reply