In many ways this is a companion piece to the post I just published on solving an issue with multi-tenant applications in Azure AD: "The Account Needs to be Added as an External User in the Tenant with Azure AD Apps". This is actually a question I see come up fairly frequently, and one that I need to resolve as I was testing different consent flows in my own apps that are registered in Azure AD. The scenario is simply this: I give consent to an application registered in Azure AD to do "things", like letting me sign in and read my profile, or read my Office 365 or Exchange Online content. Well obviously why you're doing your development (or even if you've granted consent to an app and you want to remove it), you want to remove that consent so you can do your various code tests.
If you haven't looked around the Azure portal yet, what you'll find after you've consented to an app is that it shows up in the list of Applications in your Azure directory where your account lives. So if you own the domain "steve.com" in Azure and you log in as 'someuser@steve.com', if you grant consent to "Steve's Cool App", you'll see that app listed in the applications in the steve.com domain. Unfortunately ease of use has not made it all the way into the UI in Azure yet, so you can't just click on the app up there and go "unconsent" or "delete" or whatever. Instead, we're going to have to dig into the Azure PowerShell cmdlets to do this. So, to begin, you're going to have to download and install those; you can get the bits from here: https://msdn.microsoft.com/en-us/library/azure/jj151815.aspx.
Once that's installed go ahead and start up the PowerShell command prompt. The main thing that's important to remember here is that for purposes of this discussion, an application you've consented to in Azure is really a ServicePrincipal, not something that might make sense, like an "application". Once you have the PowerShell command prompt open, the first thing you need to do is to connect to the tenant that consented to the application. You do that with this command:
connect-msolservice
After you've connected the next thing you want to do is to list all of your ServicePrincipals; you can do that with this cmdlet:
Get-MsolServicePrincipal
That will list all of your ServicePrinicpals, and if you're lucky like me, you'll see the ones that you've consented to most recently at the bottom of the list. When I do this for example, I see this as the last entry:
ExtensionData : System.Runtime.Serialization.ExtensionDataObject
AccountEnabled : True
Addresses : {Microsoft.Online.Administration.RedirectUri}
AppPrincipalId : 096539e3-0a7d-485c-b8e2-ae400780dc59
DisplayName : AADMultiTenant
ObjectId : 48ece4c1-3789-4e6c-91b4-a711145eb6d9
ServicePrincipalNames : {https://www.speschka.com/TodoListWebApp_MT, 096539e3-0a7d-485c-b8e2-ae400780dc59}
TrustedForDelegation : False
In this case, this application is the from the Azure multi-tenant sample on github that I downloaded and was working with to test multi-tenant scenarios: https://github.com/AzureADSamples/WebApp-WebAPI-MultiTenant-OpenIdConnect-DotNet. So when I want to "delete that application" so I can test the consent process again, I need to use the Remove-MsolServicePrincipal cmdlet. There are a few different overloads for using it; I use it with the -AppPrincipalId switch. You can see the value in the output above; the AppPrincipalId coincidentally is the ClientId of the application in Azure AD. So to remove my consent for this app, I run this cmdlet:
Remove-MsolServicePrincipal -AppPrincipalId 096539e3-0a7d-485c-b8e2-ae400780dc59
That's it - consent gone, and now I can start my testing all over again. There's one other kind of related point worth making. If you look at the code in the multi-tenant sample on github, it includes a bunch of the code in the Startup.Auth.cs class and you may be wondering how much of that you really need. Well without covering it all, I will just say that you need AT LEAST this part:
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = newClientCredential(clientId, appKey);
string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = newAuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID), newEFADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, newUri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceID);
returnTask.FromResult(0);
},
If you don't include this piece of code, then the AppPrincipal will never get added to your tenant. I suppose actually you might want to do that in certain testing scenarios. But in production you would not, because without this piece of code you don't get the AppPrincipal, which means that every time a user logs in they have to grant consent all over again. In most cases that's not going to be the behavior you want to display, so that's just an FYI.