Oktane18: Customer Spotlight: Managing Multiple Brand Experiences with a Single Okta Org
Mark Milchuk: Hi, everyone. Good afternoon. Welcome. Thank you for coming. It's a lot bigger group than I actually thought would be interested. Thanks, Steve. I am Mark Milchuk. I am the Director of Enterprise Architecture at the Realogy Franchise Group. With me who's going to be running my laptop will be Sami Abdul. Sami is our Identity Management Administrator for the Realogy Franchise Group. Sami and I have worked together for 10 years in identity management. A little background about myself, I have about 15 years in identity management. I started with a product called Oblix. I don't know how many of you even remember Oblix, but Oblix was bought out by Oracle, and that became Oracle Access Manager 10g. That is the current identity provider that we are using, but we are in the process of migrating off of OAM 10g on to the Okta identity management system. I'm also familiar with other identity management providers like Microsoft's Azure Active Directory. I've personally implemented the Realogy Franchise Group's security token service, which implements the following standard sign-in protocols: OpenID Connect OAuth 2.0, SAML 2, WS-FED. This security token service is integrated with our Oracle Access Manager identity management system.
Now, most of you have probably never heard of Realogy, but you've probably heard of our brands. Realogy is the global leader in residential real estate franchising. You'll probably recognize Century 21, Coldwell Banker, Coldwell Banker Commercial, ERA, Sotheby's International Realty, Better Homes and Garden Real Estate. Realogy has affiliated brands in over 15,000 offices doing business in 117 countries. Currently, we're supporting over 250,000 users in our identity tenant. For the Realogy Franchise Group, it's all about branding. Everything is branding. Every conversation we ever have is about branding. To give you an idea what I'm here to talk about today is the idea of turning this basic Okta standard sign-in experience hosted on the Okta or tenant URL into this, an unlimited number of branded login pages hosted on branded login URLs. As part of our migration, we have to sit down and obviously determine, what are our requirements when moving to the Okta identity management system? Our number one requirement, login pages must be hosted by the identity management system, not the application.
Two, we must be able to multiply brand our login pages on a single Okta or tenant. Three, Any application needs to interact with our identity management system through standardized sign-in protocols like OpenID Connect, OAuth 2 or SAML 2. Finally, of course, single sign-on between applications needed to be supported such that if a user logs into an initial application, and if he's in the same web browser session and he moves to a another application, the identity management system will not, once again, challenge him to re-enter his user credentials. Being the good little engineer that I am, I poured through the Okta documentation, and I looked what my available solutions were. First, I could use the Okta universal login page for our org, which was that standard login screen that I showed you earlier, which had limited customizability. It certainly couldn't do multi branding. The second solution was I could create my own login page using the Okta sign-in widget, which would allow me to do multi branding. However, the login page would not be hosted on the identity provider. It would be hosted at the application. Also, the application at that point would not be using standardized sign-in protocols to work against the identity management provider.
Third solution available was to completely write my own customized login page using Okta's authentication APIs but once again, this would not be hosted by the identity provider. It would be hosted at the application. It would not be using standard sign-in protocols for the application to communicate with the identity provider, and this doesn't support single sign-on, so, after I panicked for a moment, I got on the phone, and I contacted my Okta representative, Michael Anthony and Steve, and I said, "I think we have an opportunity we need to discuss." They said, "Don't worry." I explained to them what my problems were, and they said, "We put together a team over at Okta where we could sit down and talk about your concerns and what you need, and whether or not we could actually come up with the solution to help you guys." In those meetings, I explained our most important philosophy was that the identity provider must own the login page. The reason for that are as follows. One, for security reasons. This minimizes our attack service across our application portfolio. There is only one login page. The login page is protected and administered and created by our identity management team, so if anything is ever to go wrong or it doesn't work, Sami.
Two, of course, it had to provide single sign-on capabilities. This is one of the most important features in any identity management system, the idea that simpler maintainability or application programmers don't need to really know about identity management. They need to know how to integrate with identity management, but they don't have to understand all the flows that are implemented, let's say, in the Okta sign-in widget. Finally, well, not finally. Sorry. Standardized sign-in protocols. Again, applications that use standard sign-in protocols end up being loosely coupled to the identity management system, and this is important because if in the future you need to move off of whatever particular identity management system you're on, like we're doing today, you can easily typically just change the configuration information of the application pointing it to the different endpoints of the new identity provider, and the application should continue happily along.
Also, in today's world, we're building applications with OpenID Connect and OAuth, and those applications are going to be powered by the REST APIs we need to call in order to get all our additional data. Of course, those APIs are protected by OAuth and require access tokens or JSON web tokens. With our standard sign-in protocols, of course, we'd get those tokens as part of our authentication process. Finally, and very important, is the end user experience. If I'm a Century 21 user, and I'm logging into application A, and I'm presented with a login page hosted on a particular URL, I enter my set of credentials, tomorrow, if I log into application B and I get that exact same login page hosted on that exact same branded URL, I know to enter those same credentials, so there's no confusion amongst the user on which credential set to enter for any of our applications in our application portfolio. Working with the Okta team, they went, "That makes sense. We're going to try to come up with a solution in order for you to be able to start branding your login pages. The ideal architecture that we kind of came up with, which actually mimics the current architecture Realogy has with its OAM identity provider is the idea of applications, which are branded that are going to use standard sign-in protocols. To communicate with an identity provider, you will make authentication requests to the security token service. The security token service will determine whether or not the user has been authenticated. If not, we'll redirect them to a branded login page, which is hosted on a branded login URL. After successful authentication, we will return to the security token service, which will respond with the proper sign-in protocol response and security tokens back to the application, so the application can validate those tokens and trust the user and user claims associated with that token.
In today's demos, we're first going to show you an OpenID Connect sign-in protocol demonstration against a branded login page, which will return an ID token. We will then move to a second demonstration where we will show the SAML 2 sign-in protocol, which this solution builds on top of the OpenID Connect solution that we will demonstrate first, which will, again, respond with a proper SAML 2.0 response. Let's talk about, how do we build our login pages? Our login page that we're going to show you today is a standard asp.net, MVC application. It's going to incorporate the use of the Okta sign-in widget, which implements all of our identity flows for us, so we don't have to rebuild them. Most importantly, this will be hosted virtually in the identity management realm as opposed to on the application server. It will support multiple brands. We will deploy this application into Microsoft's Azure Cloud, and we will map our custom domain names to that application to give us our branded login URLs.
Mark Milchuk: We then deploy our login page web application into Azure's cloud, and then we map host names to our login page website. You'll notice, there's a demo.login and at sothebysrealty.com. There's a demo.login at bhgrealestate.com, demo.login.century21.com. These are going to be all the URLs that are branded that will host the login page for the branded user. Let's turn to the Okta administration console. For each branded login experience, we need to create an identity provider for that brand. You'll see here, as part of today's demo, we have a green brand and a blue brand. Now, these are SAML 2 identity providers. However, these identity providers will never process any SAML 2 requests, nor issue any SAML 2 responses. Their only purposes to serve is to map the assertion consumer service URL IDENTIFY, this IDP value, which the calling application, which I will show you later, will pass in to Okta as part of the standard sign-in protocol request.
This ID can then be mapped to, if we dig into the definition of one of these particular identity providers, you'll notice the IDP single sign-on URL, and this is demo.login.sothebysrealty.com, which is the domain that was mapped up in the Azure cloud for us. Again, the identity provider is nothing more than a mapping between a requested branded login experience to where that branded login experience is hosted. Okay. Now, we need an application to call our branded identity providers. We're going to start with our OpenID Connect web application. As you'll see, it is a standard asp.net MVC application. We're going to use an OWIN middleware in order to help us with our OpenID Connect implementation, so we don't, of course, have to write that. Most importantly, there's going to be the introduction of this IDP query string parameter that will be sent as part of this OpenID Connect sign-in request, set to one of those IDP values of the identity providers I pointed out previously.
We'll then go into the Okta administration console where I'll show you how to configure the OpenID Connect web application and also configure the authorization server that we'll be using for our OpenID Connect requests and responses. First, back to Visual Studio, you'll notice again, this is our OpenID Connect client web application. It's a standard asp.net MVC app. In the web config file, you'll notice we're setting the authorization server URL to the custom authorization server, we'll define in a moment, but most importantly, you'll notice here, I am doing a mapping between branded login experiences with those particular IDP values that I showed you earlier for the identity provider, the end of that ACS URL. In our startup.auth file, the OWIN middleware gives us a notification event. This notification event allows the programmer to set the IDP query string parameter in the sign-in request to the particular branded login experience that he wants, and then of course, the sign-in request is made to the identity provider. Here is our Okta administration console where we are defining our authorization server. You'll notice the issuer. This is the value we set in our web config file a moment ago, and the metadata URL. Metadata files contain multiple configuration endpoints that, depending on the technology stack you're using, you may need to use to set in your applications configuration file.
Now, in the Okta administration console, we're going to define this OpenID Connect web application. What you'll notice is there is only or only one is required to support all branding and login experiences. You'll see it's defined simply as an OpenID Connect application using a code and ID token response type. You'll notice, of course, we set what our valid login redirect URLs are and our valid logout redirect URLs. Our client ID and client secret for this application, which of course, needs to be set in the web config file of our web application. Now, I'd like to do a quick demonstration. Pray that the internet works. Look at that. First, we're going to demonstrate the generic Okta sign-in login experience. Again, this is using the OpenID Connect sign-in protocol, spinning, spinning. There we go. Again, here's the standard Okta sign-in login page, which again is hosted on the Okta tenant URL. An ID token is returned. The application validates the signature. The user is trusted. The claims are displayed for the user.
Now, let's look at this flow now using the Sotheby's branded login experience. Again, an open ID request is made to Okta. We redirect to our branded login page, which is hosted on the branded URL. In a moment, the sign-in widget will appear, and… We're actually hardwired. This is not Wi-Fi. Come on. Well, when it does show up, it'll be used … Ah, there it is. Again, this is the standard Okta sign-in widget, so we didn't have to write any of this functionality. We just needed to include it. Again, the ID token is returned, it's validated. Claims are displayed for the user. Sign out. Now, we can see the same another logging experience used, this time, using the Better Homes and Garden branded login experience. Again, the sign-in widget will show, and of course, now, we're hosted on the demo.loginbh&grealestate.com URL. Anybody from out of town? Yeah, it's a common. There it is. I don't know why it's doing that but anyway, again, the standard Okta to sign-in widget, just branded, of course, a little differently. ID tokens returned, validated, users trusted, and again, the claims are displayed. Sorry. That's the OpenID Connect solutioning.
Now, we're going to move on to talk about, well, can we get this to work with a SAML 2 sign-in protocol? Believe it or not, it is possible. However, it's going to piggyback on top of the OpenID Connect solution, so going to show you that it's going to be a simple asp.net MVC application again. It's going to use OWIN middleware to implement our SAML 2 sign-in protocol. We're going to show you in the Okta administration console that we need to define a branded app … Every branded experience you want for this SAML 2 application will have to be defined as a separate branded SAML 2 application, and all those SAML 2 application definitions will need to make use of the Open ID Connect proxy application that we're going to define because the SAML 2 applications will piggyback on top of the Open ID connect solution.
First, Visual Studio. Once again, SAML 2 web app, standard asp.net application. In the web config file, here, we are going to map branded login experiences to the Okta SAML 2 applications identity provider issuer IDs. When I show you the SAML 2 application definition, I will point out again where these IDs actually come from. In our web config file, we will set our standard SAML 2 configuration, and for every identity, every branded login experience that we want to support for this application, we will need to define a separate Okta identity provider issuer, so this is the definition for the blue brand. Obviously, in our demo, we're going to have a green brand as well, so that would be another configuration to add I'm just not showing it on the slide. In our startup.auth file, once again, the OWIN middleware gives us a notification event, which allows us to set the particular identity provider that we wish to use before the sign-in request is made. Now, let's turn to the Okta administration console. We're needing to define our applications so. The first thing you'll notice, again, as I mentioned, that every branded login experience for a SAML application needs to be defined as its own branded application. You'll notice SAML 2 blue, SAML 2 green, and SAML 2 Okta. These applications will need to use this proxy application, which we will discuss in a moment. First, the proxy application. You're going to define it as an OpenID application. It's going to be set to do code grant. However, we're never going to do anything with this. We're basically just piggybacking on the authentication flow. What's important to note here is the valid login redirect URIs, they need to be set to the SAML 2 web application URLs that will initiate a sign-in request to the Okta identity provider.
I know that sounds confusing but hopefully, it'll get a little clearer in a moment so you'll see we have two valid redirect URLs. One for the green brand, and one for the blue brand. The proxy application has a client IDENTIFY. We're going to need this in the configuration of our SAML 2 web application in a moment. Then, for this proxy app, we're going to let everyone access it because any SAML 2 application that you forever define in your Okta org will need to use this proxy app if you want to use a branded login experience. Talk about defining one of those SAML 2 specific brand applications. Here, you'll see, this is the SAML 2 blue web application definition. We will set the single sign-on URL to the application's URL that will process the SAML response and validate the SAML assertion returned by the identity provider. Here are our attribute or claim definitions that will come back in our SAML assertion. Now, most importantly, for this SAML 2 web application, we are going to use a custom login page for this application. We are going to create the login page URL, which it will use. This login page URL is built as follows. First, we're going to call the authorization server that we showed the definition for back in our OpenID Connect solution. We are going to set the client ID to the client-
Mark Milchuk: We are going to set the client ID. For the client ID of the proxy application that we just defined, we are going to set the redirect URL to the SAML2 web application URL that'll initiate a sign in request to the Okta.org. Again, this is that same URL that we defined in the ‘prop cation’ as a valid redirect URI. And then finally, you'll notice again we have this IDP query string parameter that we're going to set to the particular branded identity provider we defined earlier. So basically this will do a blue branded login experience, using the blue branded identity provider definition in Okta.
Finally, at the end of our 2 web application definition, you will see that there is a "View setup instructions" button. When you push this you'll get the identity provider for this application. This is the ID that does the brand mapping in the web config file of the SAML2 web application I pointed out earlier. And now hopefully, we're going to try to demo the SAML2 branded login experience. We're going to start with the generic Okta login experience. It's spinning ... There we go. So if anyone's done a SAML2 web application, they will notice this generic login page again, which again is hosted on the Okta tenant URL, SAML2 assertion will be returned, it'll be validated, the user will be trusted, the claims are displayed. Now if we can see that again, but this time with a Sotheby's International Realty branded login experience. What you'll notice from a user's point of view, he's logging into a different application, but it's the exact same login page every time. It's hosted on the exact same branded login URL. The user knows which credential set he needs to enter.
Also, because the sign in which it isn't up yet, I'll explain something else. What happened under the hood? A SAML2 request was made to the endpoint of the blue branded SAML2 web application. But its definition says you're going to use a custom login page, so what it did was redirect to the authorization server with that proxy app definition that then mapped you back out to our Sotheby's branded login page. So again, the user will authenticate. Very important that when he authenticates, the session cookie is set. That session cookie is what allows for single sign on, and where that's important is because what happened under the hood here is, the authorization server's response back to my SAML2 web application had a redirect URL that said, "Sign in again." So it reissues the SAML2 sign in request, but this time Okta says, "Oh, you have a session cookie, I do not need to challenge you to enter your user credentials." Therefore, the custom login page flow does not happen. Instead, the SAML2 response is created, the assertion is returned back to the web application where it is validated, the user is trusted, claims are displayed, and we can sign out. And then finally, just for completeness, we can show we can also do this with the Better Homes and Garden branded login experience. Again, it'll show up ... branded login URL, if you all trust me that it works, we can move on. Let's just move on.
All right. I'd like to thank a few members of the Okta team that worked very hard to get this to work with me, and to listen to me ramble on and on and on about why I needed things the way I needed it. I'd really like to thank Michael Anthony, I'd like to thank Steve, they're our account reps, they always deliver for us. More importantly, they make sure my voice is heard at Okta. They make sure the Tom Abbots of the world understand what I need, why I need it, and will set up meetings for me with him, to discuss future direction, or possible inclusion into the Okta product. I'd like to really thank Vishal. Vishal worked with me for two weeks to come up with that open ID connect solution. I'd like to thank Jeff Nester. He's the one that actually came up with that cute little trick for the SAML2 with the custom login page URL. And I'd like to thank Tom Abbot. Tom, after hearing about all the work that went into the solutioning and how it worked, wanted to take a meeting with me, which we talked for probably an hour and a half about what it is I was trying to accomplish, and he saw it. He saw it immediately and right away. This allowed him to put it on the Okta roadmap, so that the fruits of all this work can be enjoyed by all customers of Okta. And with that I want to turn to Nate from Okta.
Nate B: Hey everybody, I'm Nate Barbettini, I work here at Okta. I'm a PM product manager for our developer experience team. I work pretty closely with Tom Abbot and I wanted to talk about exactly what Mark was saying, how we are taking some of the stuff that Mark's working on, this use case that Realogy had and turning it into stuff that's built right into our platform. It was really great to work with the Realogy team to understand their used case, and it turned out to be a really good baseline use case for the type of things that we want to just add directly into our platform for anyone else who might be trying to do this. The way that it looks on our roadmap is, actually we have three new features that just came out into early access, actually a week or two ago, really recently. I want to just go over those features real quick with you guys.
The first one is something we're calling, Custom URL Domain. That's a fancy way of saying we're going to make it pretty easy for you to just take a domain that you own, you know, id.realogygroup.org, or whatever it is, and just seeing a map to Okta. So in your Okta configuration you can say, "Yep, I own this domain, I can prove it. Here's a TLS certificate that you can use when you host for me." And then when someone lands on that Okta hosted sign in page, instead of seeing "something.Okta.com", they see, "ID.com.yourcompany.com", or "Login.yourbrand.net". We're making that really easy to do, just built right into our platform.
We also rolled out a feature called, Custom Error Pages. That closes an extra gap where, of course we always hope that everything goes right, but in the real world something goes wrong, something's misconfigured, or a system is down and Okta isn't able to redirect your user back into your application. When that happens, we don't want the user to have this great branded experience and then if something goes wrong, then suddenly see an Okta error page. So we just gave you the ability to also customize the HTML of any error that might happen, so that you can still have your logo on there, still make it look like something went wrong but at least it still has your logo on it.
So very similar to the sign in page, you just can completely edit the HTML. We give you a little bit of templating syntax so you can put in where you want the error message to render, but otherwise you just totally control the HTML of the page. That gets the platform a lot closer to the used case that Mark was trying to solve in the first place, but it doesn't get it all the way there because, in Realogy's case, they didn't want to just customize the sign in page, they wanted to multi-customize the sign in page. They want to have multiple brands using the same shared login page, but branding it depending on which application the user is trying to sign in, which brand they're trying to interact with.
To close that additional gap we're working on a feature called, "Application Context". What that means is that the context of which application the user is trying to sign into will be available to your code that's running on that customized login page. We're still playing with the syntax a little bit. We think this is what the final syntax is going to be, but this is still in early access, so we might change it up a little bit. But basically, simply, you can use some code to get the context of what the user is trying to do, where they're coming from, and use that to customize the page even further, such as changing out the style sheet, putting a different logo on there. Or even just totally changing the layout of the page if you need to.
If this is something that you need to do, if this use case that Mark is describing is something that you are also trying to do, if you're trying to do this today, I think Mark has some code he can share at the end. He can show you how he did this. You can talk to him, figure out the solution that his solution works today. If this is a use case that you're trying to solve tomorrow in the near future, then come chat with me afterwards. We can see if our roadmap is going to line up with your roadmap and maybe the features that we're building today into our roadmap in the next couple of months, would even be able to solve your problem even easier. That's my little spiel, just wanted to let you all know what's coming up on our roadmap and how we're trying to make this even easier to do. I'll turn it back over to Mark.
Mark Milchuk: Thank you Nate. Anyone, any questions? The contact information for both Sammy and myself. But what I would really like to point out, we've created this GitHub site in support of this presentation. It has all the source code for the demos that we just ran for you, but more importantly, there is very, very, very detailed documentation that goes step by step on how to configure all of this in Okta. I've actually probably left out a few of the minor stuff, due to the restriction of time. But this GitHub site will explain it great detail. With that, I thank you for coming. If there are any questions, we have all 23 seconds left, if you can't get in it within then, I'm more than happy to step to the side and stay as long as you need, to answer any of your questions. Thank you.
Not only does Realogy manage over 250,000 customers, but they host applications for six other global real estate brands like Century 21 and Coldwell Banker. Watch this session to understand how Okta's seamless single-application log in esperience allowed for Realogy to overcome their authentication challenges.