Azure Multi-Tenant Application with Windows Live ID Authentication - azure

We are successfully authenticating the Azure AD users from different subscription using Azure AD Multi-tenant application but unable to authenticate the Windows Live ID accounts.
To authenticate the live ID accounts we use the Windows Live ID identity provider with Azure Access Control Service (ACS), its working fine with Azure AD single tenant application but we are struggling to authenticate Azure AD users across subscriptions which can only be done by using the Azure AD multi-tenant application.
We follow this blog https://msdn.microsoft.com/en-us/library/azure/dn486924.aspx and it works for Single tenant application but when we try to configure the Azure AD app to multi-tenant and configure it with ACS getting the below error.
enter image description here
Is there any approach we authenticate the Windows Live ID and use the Azure Multi-Tenant Application?

You can authenticate Microsoft Account (live id) users in a multi tenant application by skipping ACS altogether and provisioning the Microsoft Account in directory tenants. One gotcha is that authenticating with a Microsoft Account requires you to fully specify the authentication endpoints by instantiating the tenant in the URL. You cannot use the /common endpoint because that relies on the user's home tenant, and an MSA user does not have one.

You add following code in your Account controller
public void SignIn(string directoryName = "common")
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Environment.Add("Authority", string.Format(ConfigurationManager.AppSettings["ida:Authority"] + "OAuth2/Authorize", directoryName));
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
and add this block in your startup.auth.cs
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
// we inject our own multitenant validation logic
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
object obj = null;
if (context.OwinContext.Environment.TryGetValue("Authority", out obj))
{
string authority = obj as string;
if (authority != null)
{
context.ProtocolMessage.IssuerAddress = authority;
}
}
if (context.OwinContext.Environment.TryGetValue("DomainHint", out obj))
{
string domainHint = obj as string;
if (domainHint != null)
{
context.ProtocolMessage.SetParameter("domain_hint", domainHint);
}
}
context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
context.ProtocolMessage.PostLogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action
("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
//context.ProtocolMessage.Resource = GraphAPIIdentifier;
context.ProtocolMessage.Resource = AzureResourceManagerIdentifier;
return Task.FromResult(0);
},
...
}
When you click on "SignIn" ask for "Azure AD name". Pass that variable to the Account/SignIn action. If the user will be present in the mentioned Azure AD, sign-in will be successful.

Related

How to retrieve the SignIn user's group/role "MailNickName" from AAD using AAD authentication without OpenID

I have created Azure Web App with AAD authentication.
But unable to read the Signed in User group details.
I have created web app/app registration Like this https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad.
Once the Web App authenticated application redirect https://contoso.azurewebsites.net/.auth/login/done
Once AAD user authorized. we need to pull the Group details (I Need MailNickName).
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"]}");
var tenantId = ClaimsPrincipal.Current.Claims.Single(x => x.Type == "http://schemas.microsoft.com/identity/claims/tenantid").Value;
var userId =ClaimsPrincipal.Current.Claims.Single(x => x.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var httpResponse =httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/memberOf").Result;
httpResponse.EnsureSuccessStatusCode();
var jsonResult =await httpResponse.Content.ReadAsStringAsync();
/* IUserMemberOfCollectionWithReferencesPage groups;
while (groups.Count > 0)
{
foreach (Group g in groups)
{
rol.Add(g.MailNickname);
}
if (groups.NextPageRequest != null)
{
groups = await groups.NextPageRequest.GetAsync();
}
else
{
break;
}
}
return rol.Where(x => x.Length <= 8).ToList();*/
}
Note : We are not using OpenID Connect.
I need the lsit of (g.MailNickname) for the Signed User. I got unauthorized error.
Thanks in Advance.
You need to grant the application Directory.Read.All delegated permission and grant admin consent.
Find the application you registered on Azure portal->click API permissions->choose Microsoft Graph->Delegated permissions->check Directory.Read.All
Remember to click 'Grant admin consent' button.
Then change the additionaloginparams, the resource should be https://graph.microsoft.com. Refer to this article for more details(You can focus on configuring Web App to Ask for Access to Correct Resource part).

Azure Function V2 JWT - AD Authentication

I am trying to authenticate the Azure Functions v2. I am getting below error
Microsoft.AspNetCore.Authentication.Core: No authentication handler is registered for the scheme 'WebJobsAuthLevel'. The registered schemes are: Bearer. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("WebJobsAuthLevel",...)?.
below is the code I am using in Startup.cs
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.Services.AddAuthentication()
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,o =>
{
o.Audience = "https://*******************.azurewebsites.net/";
o.Authority = "http://localhost:****";
o.RequireHttpsMetadata = false;
o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
RequireSignedTokens = true,
ValidAudience = "https://***************.azurewebsites.net/",
ValidateAudience = true,
ValidIssuer = "https://sts.windows.net/***************-5********2**/",
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true
};
});
}
}
changed the code but still getting same given error. Which one I am missing?
Consider using the Azure App Service Authentication/Authorization feature (also known unofficially as EasyAuth). If you follow the express flow in the Azure Portal, it will create an AAD V1 application registration for your function application, and automatically configure your app to allow authentication using AAD. If you then set Action to take when request is not authenticated to Login with Azure Active Directory, only authenticated requests will be authorized to make any request to your application.
EasyAuth has built in support for accepting Bearer tokens for your AAD app registration, as well as some other OAuth2/OIDC flows for AAD and our other supported identity providers (Facebook, Google, Twitter). Through this feature, you shouldn't need to add any code on your end, it will all be handled by the Azure platform.

Is it right way to use Owin.Security.ActiveDirectory library with AAD B2C

We have two Application registered in the same AAD B2C tenant via "New" and "Old" portal.
Authentication with "Old" Application credentials works correct.
With "New" Application credentials - error appears:
IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
'
Is it right way to use Microsoft.Owin.Security.ActiveDirector library (to protect ASP.Net Web API) with Application registered in AAD B2C tenant.
P.S. My question is based on this post.
You should only create applications via the Azure AD B2C blade in the new Azure portal (portal.azure.com).
Do NOT create applications for Azure AD B2C using the classic Azure Portal (manage.windowsazure.com).
If you want to secure a WebApp, you should use Owin's OpenIdConnectAuthentication. This document has more details on how to do this: Sign-Up & Sign-In in a ASP.NET Web App
If you want to secure a WebAPI, you should use Owin's OAuthBearerAuthentication. This document has more details on how to do this: Build a .NET web API
Samples configuration of a WebApp:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Generate the metadata address using the tenant and policy information
MetadataAddress = String.Format(AadInstance, Tenant, DefaultPolicy),
// These are standard OpenID Connect parameters, with values pulled from web.config
ClientId = ClientId,
RedirectUri = RedirectUri,
PostLogoutRedirectUri = RedirectUri,
// Specify the callbacks for each type of notifications
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = OnRedirectToIdentityProvider,
AuthorizationCodeReceived = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed,
},
// Specify the claims to validate
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name"
},
// Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
Scope = $"{OpenIdConnectScopes.OpenId} {YourScope1} {YourScope2}"
}
);
}
Samples configuration of a Web API:
public void ConfigureAuth(IAppBuilder app)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
};
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
});
}

Not allowed users are authentication in my Azure AD Application Multi Tenant

I have two tenants configured in my Azure AD. My users are authentication with successful in my tenant but others users that are another tenant has access in my applications.
What's wrong with my application? I'm using OpenId Connect protocol in my code, for exemple:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = (context) =>
{
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
context.HandleResponse();
return Task.FromResult(0);
}
}
});
Am I setting something wrong on my Azure?
Someone help me?
Thanks,
Vilela
I have two tenants configured in my Azure AD.
The tenants are corresponding to the Azure Active Directory. So when there are two tenants that means you have two different Azure Active Directory.( refer here about the detail concept)
And to enable the multi-tenat app, we need to enable it from the old Azure portal and locat you app. Then you can set it by refering the figure below:
Update( limit the sepcifc tenants to access the multi-tenants app)
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
// instead of using the default validation (validating against a single issuer value, as we do in line of business apps),
// we inject our own multitenant validation logic
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// we use this notification for injecting our custom logic
SecurityTokenValidated = (context) =>
{
// retriever caller data from the incoming principal
string issuer = context.AuthenticationTicket.Identity.FindFirst("iss").Value;
var issuer1 = "";
var issuer2 = "";
if ((issuer!=issuer1)&& (issuer != issuer2))
// the caller was neither from a trusted issuer - throw to block the authentication flow
throw new SecurityTokenValidationException();
return Task.FromResult(0);
}
}
});

Azure B2C with Web API

The examples I've seen for using Azure B2C with Web API show app.UseOAuthBearerAuthentication (as shown below), however my ASP .NET 5 Web API project uses IApplicationBuilder (not IAppBuilder) and UseOAuthBearerAuthentication does not exist. I've tried app.UseOpenIdConnectAuthentication, however I believe this uses cookies and I couldn't get it working using a Xamarin app as a client. I've tried app.UseWindowsAzureActiveDirectoryBearerAuthentication but I believe this is for standard Azure AD (not B2C) is that true? Any ideas how to get Azure B2C working with the very latest ASP .NET Web API?
Thanks!!!
public void ConfigureAuth(IAppBuilder app)
{
TokenValidationParameters tvps = new TokenValidationParameters
{
// This is where you specify that your API only accepts tokens from its own clients
ValidAudience = clientId,
};
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(aadInstance, tenant, "v2.0", discoverySuffix, commonPolicy)))
});
}
This works for me. I hope it helps someone else who is looking to use Azure B2C with the latest .NET Web API framework:
public void ConfigureAuth(IApplicationBuilder app, IOptions<PolicySettings> policySettings)
{
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
MetadataAddress = "https://login.microsoftonline.com/[my-tenant].onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_my-signup-signin-policy",
Audience = "[My-Azure-App-Guid]",
Events = new JwtBearerEvents
{
OnTokenValidated= ctx =>
{
var nameClaim = ctx.AuthenticationTicket.Principal.FindFirst("name");
if (nameClaim != null)
{
var claimsIdentity = (System.Security.Claims.ClaimsIdentity)ctx.AuthenticationTicket.Principal.Identity;
claimsIdentity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, nameClaim.Value));
}
return Task.FromResult(0);
},
OnAuthenticationFailed = ctx =>
{
ctx.SkipToNextMiddleware();
return Task.FromResult(0);
}
}
});
}
If the JWT token is available in your client, then you can use JwtBearerAuthentication in the Web API. The JWT issued by Azure B2C ( social logins) can be used as a token to get authenticated in the Web API.
Refer to https://github.com/sendhilkumarg/AzureB2CWebAppAndAPIAuthentication
In this sample the client is a web app

Resources