jpd.ms

on-prem = legacy

Updating ADFS 3 for WIA on Windows Tech Preview

If you’re using the Windows Technical Preview, you may notice that ADFS presents you with a Forms login instead of using WIA from IE on a domain machine. This little chunk of powershell includes most of the major browsers that support WIA – you can plunk this into your ADFS server and get it going:

Set-AdfsProperties -WIASupportedUserAgents @("MSIE 6.0", "MSIE 7.0; Windows NT", "MSIE 8.0", "MSIE 9.0", "MSIE 10.0; Windows NT 6", "Windows NT 6.4; Trident/7.0", "Windows NT 6.4; Win64; x64; Trident/7.0", "Windows NT 6.4; WOW64; Trident/7.0", "Windows NT 6.3; Trident/7.0", "Windows NT 6.3; Win64; x64; Trident/7.0", "Windows NT 6.3; WOW64; Trident/7.0", "Windows NT 6.2; Trident/7.0", "Windows NT 6.2; Win64; x64; Trident/7.0", "Windows NT 6.2; WOW64; Trident/7.0", "Windows NT 6.1; Trident/7.0", "Windows NT 6.1; Win64; x64; Trident/7.0", "Windows NT 6.1; WOW64; Trident/7.0", "MSIPC", "Windows Rights Management Client")

Why?

In version 3, ADFS tries to intelligently present a user experience that’s appropriate for the device. Browsers that support WIA (like IE) provide silent sign on, while others (like Chrome, Firefox, mobile browsers, etc) are presented with a much more attractive and user friendly forms-based login. This is all automatically handled now, unlike before where users with non-WIA devices were prompted with an ugly and potentially dangerous basic 401 authentication box (if they were prompted at all).

This means you can now design a login page for non WIA devices that might include your logo, some disclaimers or legal text.

IMG_0001

iOS 8x and ADFS 3

TenantDbContext for Table Storage

For anyone who’s used the ASP.net MVC templates with multi-organizational authentication, you’ll inevitably end up with a bunch of generated entity framework goo for keeping track of organizational certificate thumbprints for orgs who have logged into your app. This is lame. We’re creating two tables with a single column each in SQL?! I’ve never heard of a better use of table storage. Not to mention I’ve got to now pay for a SQL Azure instance, even if my app doesn’t need it.

This speaks to a larger issue – how frequently are we, as developers, using SQL by default? Do we really need relational data? Are we enforcing constraints in our service layer as we should? We are?! This makes SQL even more ridiculous in this scenario.

I decided to build one that uses table storage. You’ll need a few things

a) the source

b) update your web.config to indicate the issuer registry type

The VS solution is on github here: https://github.com/johndandison/net-table-issuer-registry

It’s dependent upon Azure configuration and Azure storage. Licensed under MIT, if you find it useful I’d just ask you drop me a line and let me know what neat thing you’re working on!

Smartphones Don’t Seem Very Smart Anymore

That headline may come across as rather spoiled, a la Louis CK’s always entertaining rant against people complaining about wifi on airplanes (you’re in a chair. In the air). The recent release of the giant iPhone got me reconsidering what I want in a phone, and it made me realize that Microsoft’s mobile offering is brilliantly ahead of its time, while its recent pivot is incredibly disappointing.

Rewind

I’ve flown the Windows Phone banner since 2011, when I first got a Samsung Focus. I had an iPhone 4 for work and while it was fine, the freshness of WP was irresistible. I still have that Focus, actually. Sure it was limited at first – not many apps, some rather glaring omissions (copy/paste, anyone)? But the live tiles were excellent, the integration with other Microsoft services was top notch and the hubs were excellent. In fact, the hubs were what sold me on Windows Phone. All of my social stuff in one interface? Music? Pictures? Each one had its own hub, dedicated to the function it was supposed to do. I even bought my wife one, an HTC HD7, for Valentine’s Day, plus a Zune Pass. It was great. Time went on, and more phones were released, some of which I bought, like the bright blue Lumia 900. That thing was a beast. Carolina Panthers blue, amazing screen and the fastest WP money could buy.

lumia900cyan

How slick is that? Great design, amazing to hold and looked fantastic.

Fast forward to now, I’ve gone through a few more, Lumia 920, 925, 1020 and (my current phone), a 1520, each one better than the one before.

The release of WP8 promised even more awesome stuff. We saw new tile sizes, BitLocker, IE10, SD card support – a slew of new stuff. Things were looking up.

Enter WP 8.1

The future. Credit: virtuaniz.com

The future. Credit: virtuaniz.com

WP 8.1 ushered in a new era of ‘completeness’ for WP. IE11 is onboard, including much broader HTML5 compatibility, plus support for all kinds of new sizes, internals and some pretty slick interface tweaks. Not to mention the Notification Center, and of course, Cortana.

But there’s another change WP8.1 brought in that feels like a massive step backward and plays to Windows Phone’s only significant weakness – third-party app support.

I know app counts and the like on WP are a running joke, but there’s a reason I bring this up – most of the hubs have been abandoned in favor of apps. Take the people hub, which I used to spend the majority of my phone time in – it’s now severely crippled by requiring an external app to source the info, as well as requiring that app to interact with the source that surfaced it (e.g., Facebook, Twitter, etc). The Me tile, which used to contain social notifications is now just a shell of what it was before – nothing useful at all, just a picture of myself and an option to check in. What does check in do? Open an app. sigh. I’ll come back to this later.

App Gap?

I picked up an iPad a week ago to do some Azure testing. I haven’t used an iOS device since the iPhone 4 in 2011, so I was curious to see how things had improved. I’ve got a Nexus 7 and a Nexus 5, which I used mostly for testing apps and to give my Google Glass a mobile connection (I keep the Nexus 5 in my bag). I’ve never been a huge fan of Android – I understand lots of people like it, but it’s just not for me.

But I missed the tiles – the home screen is still just a bunch of icons. No passing data, nothing – just icons. Android is the same way.

Anyway, so I’ve got this new iPad, and it’s pretty slick – but the quality and speed of the applications was immediately apparent. And I immediately got sad. Seeing the gap between the quality of iOS apps v. Android apps brought me to a pretty terrible conclusion:

If Android is this far behind iOS, Windows Phone is…never going to see quality apps.

Thus my sadness. As much as I love the platform, it just can’t compete when it comes to apps. How can I, as an indie dev (I don’t do any mobile at my current gig, at least not right now), get developers to give a shit about the platform? Facebook doesn’t care, Twitter doesn’t care – and judging by the quality of what’s in the stores today, developers don’t care either. It’s either a half-ass attempt at porting an existing app or it’s someone’s less-than-brilliant interpretation of Microsoft’s modern design language. In short, the vast majority of apps that exist on the platform are shit.

Function-centric vs App-centric

And here inlies the problem. WP can’t compete with apps. This is not opinion, it’s fact. Look at the ratings in the Windows Store(s) – they’re atrocious. Apps are consistently non-performant, released-once and never updated, don’t work or are just generally of poor quality. Lots of major services don’t even produce apps – and if they do, they are perpetually in beta (looking at you, Instagram), or Microsoft builds them themselves (e.g., Facebook). Sure, there are third-party developers who do amazing things, but they are few and far between (note – someone needs to make a Readit-style reddit app for iOS – Readit is easily the best of breed right now).

Go do a quick web search for ‘Xbox Music WP8.1′ – I’ll wait. Back? It’s definitely another casualty of the ‘let’s make everything an app’ decision. The reviews are atrocious, and even now, with a dedicated team + about a dozen releases, it’s still nothing like what it used to be.

Context Awareness is the ‘next big thing’™

But Windows Phone’s strength was always in context-awareness. The hubs focused on what you wanted to do, and surfaced relevant data and actions. The tiles, when pinned, were updated with relevant information based on what you wanted to do – want to pin a specific stock in your portfolio? Cool, pin away. Chat was unified between SMS, Windows Live, Facebook – seems familiar, eh Google Hangouts? WP had this in 2011.

Me tile notifications centered all of your social updates (retweets, wall posts, linkedin (lol) interactions) into a single feed. “I want to see what’s happening with my network,” you’d say, and the Me tile & people hub delivered.

Cortana takes context sensitivity to the next level:

Remind me next time I talk to my wife to ask her about the company picnic.

Next time I talked to my wife, I got a popup reminding me what I asked to be reminded about.

Next time I’m at Lowe’s, remind me to pick up 8 G2 halogen bulbs.

Upon arriving in the Lowe’s parking lot, I’m reminded (from the previous weekend, no less) to get my bulbs.

Even better, Cortana can remind me about flights, news, topics, weather, traffic, all kinds of things, based on my behavior and implicit/explicit metadata. Some things I told her about, others she gleaned from email, searches, messages, etc.

But Microsoft’s desperation to appease the masses and move WP has resulted in the ‘app for everything’ decision. It certainly has its merits, faster updates, more ‘xxx,000 apps in our store!’ ads, etc – but I think it weakens the core strength of what WP is all about.

It’s an app centric world…for now

So again, we’ve ended up in the prickly spot where Microsoft’s released something brilliant, but it’s the wrong time. iOS and Android are app launchers – there’s nothing inherently ‘smart’ about the OS. Sure, more things are starting to poke in, but for the most part, the ‘innovation’ is all left up to third-party developers. I don’t want to be in and out of apps all day long. I want to see what’s relevant at a specific time, or in a certain place, or…

And people don’t care about context. In emerging markets, just the fact that there’s a thing in your hand connected to the internet and it didn’t cost a fortune is a miracle in itself. Think those people are going to bitch about app quality or availability?

First-world consumers don’t appear to care about context either, at least right now. Hopefully, this changes, but Microsoft’s got to focus their message. It’s OK that WP doesn’t have 1 million apps.

Microsoft – reintegrate with major players. Bring back and modularize the hubs to allow third party access (or at least make it easier for you to maintain them) without all of the pain of these terrible third-party apps.

Integration and context are the next big winners. Opening 46 different apps to do your work daily will get tiresome. We don’t need apps for every website on the planet. We need focused, relevant information without the noise.

Unfortunately, I don’t know where the platform goes from here. Nadella’s clearly focusing mobile dev where the money is, as the Microsoft apps on other platforms are very good (seriously, almost every service I use has an outstanding app on iOS), while the WP equivalents are hit or miss (see Skype).

I swapped my 1520 for a friend’s 5s for a week while I consider a big-ass iPhone 6. I have no idea what I’ll end up using daily, but I’ll say this. This damn 5s is tiny. I have no idea how people use this phone daily.

Headless Azure AD User Creation

If you’ve spent any time with the Azure Graph API, it’s pretty sweet. Federated identity for the masses, with almost zero drama. Up until now I was mostly doing logins, queries, etc. with Azure AD, but for my latest project, I need to create both new domains and new users in those domains. I haven’t tackled creating new domains yet, because that looks like it’s going to be a royal PITA (automating powershell? ick) – but I kicked down the user path today. Went pretty well, until I got stopped cold adding a user.

Here’s some code

Adding a user with ADALv2 + the Active Directory Graph Client is pretty easy. Both are NuGet packages and simplify the process considerably. You can also post the JSON yourself, which you can find here on MSDN.

But I’m using ADGC, so here’s a quick snip of the required fields you’ll need to get a user created:


var gc = new GraphConnection(accessToken); //get this below
var pp = new PasswordProfile() //required
{
  ForceChangePasswordNextLogin = true,
  Password = "Watermelon1!"
};
var u = new User
{
  DisplayName = displayName,
  UserPrincipalName = upn,
  PasswordProfile = pp,
  MailNickname = displayName.Replace(" ", string.Empty),
  UsageLocation = "US",
  AccountEnabled = true,
  ImmutableId = Guid.NewGuid().ToString()
};
try
{
  var p = gc.Add(u);
  Console.WriteLine("Created {0}, immutable ID: {1}", p.UserPrincipalName, p.ImmutableId);
}
catch (GraphException ex)
{
  Console.ForegroundColor = ConsoleColor.Red;
  Console.WriteLine("{0}: {1}", ex.ErrorMessage, ex.ErrorResponse.Error.Message);
}

Pretty straightforward…until you get to

gc.Add<user>(u);</user>

chances are you’ll blow up with a 403 Forbidden. In fact, chances are high, like 100% this will happen (if it doesn’t let me know).

Graph Read/Write

For whatever reason, and I’m still trying to figure out exactly why, the ‘Read and write directory data’ permission doesn’t appear to allow adding users. I’m assuming this is because they want a user who’s in one of the principal management roles, like User Administrator (see this post for some info on that), as opposed to allowing app principals to do this. The long and short is that the Graph API wants you to go through an OAuth browser flow to delegate a token from a user with the appropriate permissions. If you’re using ADALv2, there’s no

AcquireToken

overload that’ll do this. This is fine, unless you want to automate the creation of these users.

What are you to do?

Fortunately, we can use the OAuth password grant_type to request a token with only a user’s username & password.

AccessTokens & the Graph

You’ll need a few things to get setup. I’m not going to go into much detail here, because if you’re encountering this issue chances are you’re already well setup. We need to request a token from the AAD STS, including both the user’s username/password, as well as the client ID and secret of the app you’re developing. Here’s a sample:

var reqUri = "https://login.windows.net/YOUR TENANT ID OR NAME/oauth2/token";
var postData = "resource=00000002-0000-0000-c000-000000000000&client_id={0}&grant_type=password&username=john%40mytenant.onmicrosoft.com&password=nicetry&scope=openid&client_secret={1}";
var wc = new WebClient();
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var response = wc.UploadString(reqUri, "POST", string.Format(postData, AppId, EncodedKey));
var tokenData = JObject.Parse(response);
return tokenData["access_token"].Value();

Let’s deconstruct this request a bit, shall we?

https://login.windows.net/YOUR TENANT ID OR NAME/oauth2/token

This is where we’re posting our token request

PostData

The main chunk of our request.

resource The resource you’re trying to access. In this case, it’s the graph, which always has this ID: 00000002-0000-0000-c000-000000000000
client_id your app’s client ID
client_secret Important – make sure to URL encode your key before putting it here
grant_type password
username your UPN (e.g., blah@tenant.onmicrosoft.com)
password this should be obvious
scope Get data in the OpenID Connect format: openid

And make sure you URL encode the form/values before submitting, otherwise it’s 400s for you.

And that’s it

Provided you got a token back and didn’t have any problems with the request, you should be able to tack that access token into the header

Authorization: Bearer ...access token...

or you can stuff that into

new GraphConnection(accessToken)

if you’re using the Graph Client wrapper.

Create away! You’re off.

srs

I’ll be at SharePoint Saturday, come out!

I’ll be speaking at SharePoint Saturday in Charlotte on September 20th. My session is on building a ‘shim’ for passive logon to Microsoft Online Services (Office 365, Azure, any federated apps) so you can do whatever kind of wild and crazy business logic you need to do. Should be fun!

Azure Admins vs. Azure AD Admins

This is a point that’s a bit ambiguous. I’m an Azure Service administrator, so I should be able to access the Azure AD associated with that tenant, right?

In a word, no.

TL, DR

If you need access to Azure Active Directory to add apps, users, etc – it’s pretty simple. It’s something we get a lot whenever one of our clients is using Azure, has granted us Azure service admin rights (E.g., Azure co-administrator), but we’re still asking for more access.

You can do this at the Azure portal (http://manage.windowsazure.com) or, for adding a new user in your org or setting permissions to existing people in your org, the Office 365 Admin Portal (http://portal.office.com).

Your Azure AD administrator (if you’re the creator of the account, this should be you, otherwise it’s time to track down the admin) just needs to add you. You can add

  • A new account in your organization – this creates a brand new account in your Azure AD tenant. No different from creating a new cloud-based user for O365.
  • An existing Microsoft Account – for sharing with the plebs who don’t have an Office account
  • An existing organizational account in another directory - for sharing with other organizations that use Azure AD (e.g., jpd.ms or cardinalsolutions.com).

Once the account is in Azure AD, you can set an access level. More info on access levels below.

Office Portal

Adding someone from the Office portal is easy. Open the portal as an admin, go to users and get crackin’ – but note, the Office portal only allows you to add users to your own organization. Could you imagine the chaos if you had options to add users from other orgs in here? LOL

office portal

But – you can add rights to an existing user from within the Office portal. Find the user in the list and you can set their access levels in there. Here’s my Live account, which was already added to my AD – I can set admin rights right from the portal.

2-op

 

Azure Portal

You can do everything from in here. Let’s dig in. Head into the Azure portal and find Active Directory in the left nav. If you don’t see your directory and you’re a member of multiple Azure subscriptions, click the Subscriptions filter to make sure you find the right one.

Once you’ve found your directory, click it and go to the Users header – here we’ll add a new user and grant them rights to AD. Alternatively, if you already see the account you want to grant access to, you can do that from in here as well.

1-adduser

Pick one of those three options (they’re outlined above) – if it’s not a valid account for the type you picked, when you try to go the next step, it’ll bomb out:

badacct

 

Otherwise, when you click next, you’ll be able to both set a name & display name for the new user (so that your Xbox name ‘N00b Slay3r 123′ doesn’t show up in your corporate apps) and grant an access level. Once you click the check, that new user is ready to go.

2-user

Role Play

Let’s talk about roles for a minute – you can find comparisons of each role here (http://msdn.microsoft.com/library/azure/dn468213.aspx) – I’m not going to repeat any of that.

Global administrators – if you’re using Azure for anything beyond test/dev, or if you’re using it with Office 365/Intune/CRM, you probably want as few global administrators as possible. The Global part of global administrator is just that – quite global.

So what’s an admin to do when he/she has devs clamoring to add apps? I can’t seem to find anything ‘official’ about what access levels have access to add applications to your Azure AD – but it appears that User administrators do have this right. It makes sense, since ‘user administration’ is really principal administration, and all of these apps are new principals.

If you only want to give your devs access to add new apps, User Administrator might be a good role for them.

DocuSign + SharePoint Online

Document signing + SharePoint Online with non-licensed users flew across my desk at WTFHQ today. Here’s the basic requirement:

Licensed users need to store PDFs in SharePoint while getting them digitally signed by non-licensed SharePoint users. Preferably without requiring creating External Users in SharePoint.

I’m happy to report this works quite easily with DocuSign + SharePoint Online. You’ll get SharePoint doc lib integration e.g., the context menu will offer you options on documents like ‘Sign with DocuSign’ and ‘Get Signatures with DocuSign.’

We’ll start with the main case – a licensed SharePoint user needs to get a document signed by a non-SharePoint user. It’s really easy.

It’s really pretty easy.

When you use the ‘Get Signatures with DocuSign’ option, you’re sent over to DocuSign, where you login (either with your Office 365 account or your DocuSign account), and it’s all vanilla from there – mark the required fields to collection from the target and drop their email addresses into the invitation field.

 

1-get

Document library integration

Invite non-licensed users to sign

Invite non-licensed users to sign

The target gets an email, inviting them to sign the document. When they click the link, they’ll go directly to DocuSign to sign the document, no SharePoint account required. They get an option to download the document, and the signed copy goes back into your document library. For our scenario, we’re finished.

Mail received by the target signer

Mail received by the target signer

Signed document automatically back in SharePoint library

Signed document automatically back in SharePoint library

Library Post

If you’re here wondering why the Library Post SharePoint app isn’t working, I’ve got some news for you. Unfortunately, it’s not good news, as I’m currently unable to access, manage or maintain the application. I built it at my former employer, who doesn’t have the resources to maintain it. I’m working on transferring control and republishing the app so that I can support it, but working out the details is taking some time.

The app’s Client ID has expired, so any calls it attempts to make into SharePoint will fail, which is why some of you are seeing infinite redirects.

I’m terribly sorry for the inconvenience.

As soon as I have more information to share, I will.

Azure Cloud Service Endpoint ACLs

Recently, Azure VMs got endpoint ACLs – this is a great addition and one of the biggest things I missed from AWS’ security groups. Using them on VMs is great and all, but what about cloud services? Since VMs are instances within a cloud service, it’s certainly possible, but how can we configure them as such? Fortunately it’s pretty easy.

No soup

First you’ll need to snag Azure SDK v2.3 and make sure your ServiceConfiguration.<env>.cscfg is at the latest schema (as of today, that’s 2014-01.2.3).

Head on in to ServiceConfiguration.Cloud.cscfg – these restrictions are obviously cloud-only – and add your chunk of config. Intellisense should pick this up and make it much simpler.

What’s nice is you can define your rules in total under AccessControls, then assign them as you need them to specific endpoints.

Here’s a sample allowing a few single IPs + a range and denying everyone else. These are executed in order, so be aware of the order tag.

<NetworkConfiguration>
<AccessControls>
<AccessControl name=”DenyAllExceptDevelopment”>
<Rule action=”permit” description=”stuff” order=”100″ remoteSubnet=”198.51.100.194/32″ />
<Rule action=”permit” description=”thing” order=”101″ remoteSubnet=”192.0.2.167/32″/>
<Rule action=”permit” description=”biz” order=”106″ remoteSubnet=”203.0.113.0/24″/>
<Rule action=”deny” description=”theinternet” order=”200″ remoteSubnet=”0.0.0.0/0″ />
</AccessControl>
</AccessControls>
<EndpointAcls>
<EndpointAcl role=”AzureService.Thing.Stuff” endPoint=”Endpoint1″ accessControl=”DenyAllExceptDevelopment” />
</EndpointAcls>
</NetworkConfiguration>

Denying Access through ADFS + Yammer

Start here if you haven’t already.

We’ll start with the last example – I’m piloting Yammer, I’ve got some users I want to grant access, but a whole lot more I want to deny. In the case of Yammer and likely some other RPs who don’t understand the Permit/Deny claim, you’ll have to manipulate something else to force the RP to boot you out. In Yammer’s case, they use the email address as the SAML_SUBJECT, which makes them pretty easy to poke.

Really, you should just update to ADFS 3.

But since that’s easier said than done, here’s how to make Yammer deny access to people using ADFS claims transformation rules.

Recursion? Did you mean recursion?

You’ll note from the previous post that we were denying users based on extensionAttribute1. This isn’t going to work any more, since Yammer doesn’t process the Deny claim, and punishes your insolence by stuffing you into an infinite redirect loop. The first thing you’ll want to do is remove any Issuance Authorization policies you have and put back ‘Allow all users.’

Next, we need to break users where extensionAttribute1 doesn’t equal false.

Persona Non Grata

In the case of Yammer, it’s easiest to just send in an invalid email address. Not invalid as in syntactically incorrect, but invalid for your organization.

That’ll give users a proper error message, informing them of their denial.

Two rules should do the trick (and you could probably get it down to a single composite rule) – one to transfer the email address to the SAML_SUBJECT and one to overwrite that claim if the user doesn’t have the requisite attributes.

To overwrite the claim (as opposed to adding a second value to the same claim), your issue statement should include the Issuer, OriginalIssuer and ValueType as the existing SAML_SUBJECT claim.

Something like this:

EXISTS(emailClaim:[Type == “http://schemas.microsoft.com…/emailAddress”]) && NOT EXISTS(c:[Type == “http://schemas.jpd.ms/unique/ad/Authorized”, Value == “true”])
=> issue(Type = “SAML_SUBJECT”, Value = “FAKE@domain.com”, ValueType = emailClaim.ValueType, Issuer = emailClaim.Issuer, OriginalIssuer = emailClaim.OriginalIssuer);

« Older posts

© 2014 jpd.ms

Theme by Anders Noren, modified by jpd Up ↑