Usage of the /common endpoint is not supported for such applications created after '10/15/2018' issue - azure

Similar issue here. I have checked the answer and try to implement all the possible forms of link in my startup.cs class with the following code:
var idClient = ConfidentialClientApplicationBuilder.Create(appId)
.WithRedirectUri(redirectUri)
.WithTenantId(tenantId)
.WithClientSecret(appSecret)
.WithAuthority(Authority) // Authority contains the link as mentioned in the page(link attached above)
.Build();
I still get the similar error:
"OpenIdConnectMessage.Error was not null, indicating an error. Error: 'invalid_request'. Error_Description (may be empty): 'AADSTS50194: Application 'xxx-xxx-xxx-xxx-xxxx'(ASPNET-Quickstart) is not configured as a multi-tenant application. Usage of the /common endpoint is not supported for such applications created after '10/15/2018'. Use a tenant-specific endpoint or configure the application to be multi-tenant.
Trace ID: xxx-xxx-xxx-xxx-xxxx
Correlation ID: xxx-xxx-xxx-xxx-xxxx
Timestamp: 2022-06-11 05:33:24Z'. Error_Uri (may be empty): 'error_uri is null'."
The combination of links I have used in variable Authority are the following: "https://login.microsoftonline.com/MY_TENANT_NAME" and "https://login.microsoftonline.com/MY_TENANT_ID"
I am being redirect to login page but after entering credentials OnAuthenticationFailedAsync method is being executed. This is the code of my startup class:
[assembly: OwinStartup(typeof(Web.Startup))]
namespace Web
{
public partial class Startup
{
// Load configuration settings from PrivateSettings.config
private static string appId = ConfigurationManager.AppSettings["ida:AppId"];
private static string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"];
private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
private static string graphScopes = ConfigurationManager.AppSettings["ida:AppScopes"];
private static string tenantId = ConfigurationManager.AppSettings["ida:tenantId"];
private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
public static string Authority = "https://graph.microsoft.com/"+ tenantId;
string graphResourceId = "https://graph.microsoft.com/";
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = appId,
Authority = "https://login.microsoftonline.com/common/v2.0",
Scope = $"openid email profile offline_access {graphScopes}",
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
TokenValidationParameters = new TokenValidationParameters
{
// For demo purposes only, see below
ValidateIssuer = true
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailedAsync,
AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync
}
}
);
}
private static Task OnAuthenticationFailedAsync(AuthenticationFailedNotification<OpenIdConnectMessage,
OpenIdConnectAuthenticationOptions> notification)
{
notification.HandleResponse();
string redirect = $"/Home/Error?message={notification.Exception.Message}";
if (notification.ProtocolMessage != null && !string.IsNullOrEmpty(notification.ProtocolMessage.ErrorDescription))
{
redirect += $"&debug={notification.ProtocolMessage.ErrorDescription}";
}
notification.Response.Redirect(redirect);
return Task.FromResult(0);
}
private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedNotification notification)
{
var idClient = ConfidentialClientApplicationBuilder.Create(appId)
.WithRedirectUri(redirectUri)
.WithTenantId(tenantId)
.WithClientSecret(appSecret)
.WithAuthority(Authority)
.Build();
string email = string.Empty;
try
{
string[] scopes = graphScopes.Split(' ');
var result = await idClient.AcquireTokenByAuthorizationCode(
scopes, notification.Code).ExecuteAsync();
email = await GraphHelper.GetUserDetailsAsync(result.AccessToken);
}
catch (MsalException ex)
{
System.Diagnostics.Trace.TraceError(ex.Message);
}
notification.HandleResponse();
notification.Response.Redirect($"/Account/SignInAzure?email={email}");
}
private static string EnsureTrailingSlash(string value)
{
if (value == null)
{
value = string.Empty;
}
if (!value.EndsWith("/", StringComparison.Ordinal))
{
return value + "/";
}
return value;
}
}
}
My application is for single tenant so please don't suggest me to change the setting and make it for multi-tenant.

Please check below points:
After trying to change it to specific tenant i.e.;
After changing to Ex: - https://login.microsoftonline.com/contoso.onmicrosoft.com (or tenant id),
please save changes ,refresh portal / everything and try again.
If still it shows the error , check if the Application is registered to the Azure AD Tenant as Multi Tenant Application.
Then if it still remains check if the account is actually on Azure
AD ,as this error can occur when the user credentials you are trying
to use does not belong to the same tenant where the application is
actually registered in.
If it is different tenant and you are trying to access from different
account, then you may need to change its supported account types to
any organizational directory or you need to check for correct
credentials. If not check everything or create a new app registration
.
Also please check this "Use a tenant-specific endpoint or configure the application to be multi-tenant" when signing into my Azure website for possible
ways to solve the issue.
Else you can raise a support request
References:
msal - MsalException: Applicationis not configured as a multi-tenant
application. Android - Stack Overflow
Use single-tenant Azure AD apps with Microsoft Graph Toolkit -
Waldek Mastykarz

Related

Azure authentication redirecting to undesired URL

I'm building an Azure AD authentication, let's say my application url is https://hostname/applicationName/Default.aspx so after hitting this url user is redirected to Azure login.
The issue is that even if an user is not part of the AD group still they are being redirected to the default page of application instead of throwing invalid user message.
Can someone let me know where to look for, below is a snippet of the code I'm using in app startup.cs:
private static string clientId = ConfigurationManager.AppSettings["ClientId"];
private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["Authority"]);
private static string tenantId = ConfigurationManager.AppSettings["Tenant"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["redirectUri"];
string authority = aadInstance + tenantId;
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
RedirectUri = postLogoutRedirectUri,
PostLogoutRedirectUri = postLogoutRedirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.IdToken,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
}
);
}
The redirectUri in my web.config file is https://hostname/applicationName/Default.aspx
In my home page of the application I've the following code in Page_Load()
if (!Page.IsPostBack)
{
if (!Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = ConfigurationManager.AppSettings["redirectUri"] },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
// Is this RedirectUri property correct?
}
//Application code
}
I've set the following in startup.cs
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
}
Let me know if any additional data is needed.
According to your description 'if an user is not part of the AD group still they are being redirected to the default page of application', I assumed that you may set the value of 'ConfigurationManager.AppSettings["Tenant"];' as 'common'.
I have tested in my place and when I set the tenant id of my organization, and I can't login in with a outside user. And with the value of 'common' that means any users could access the application so that I can successfully sign in with the user account which can't use to login just now.
Pls let me know if it doesn't work.
You have a couple of options depending on the scenario that you are trying to achieve.
If what you want is users not part of your Azure AD tenant to not be able to log in, then you should ensure the tenant property is not 'common' but your own tenant ID which you can get from Azure portal as below
If what you want to achieve is a more involved process of group-based AuthZ you can refer to this sample from Microsoft for all the details

MSAL error "parsing_wstrust_response_failed" when trying to use AcquireTokenByIntegratedWindowsAuth

I'm attempting to acquire a token from AD or Azure AD but my call to AcquireTokenByIntegratedWindowsAuth results in this:
MSAL.Desktop.4.14.0.0.MsalClientException:
ErrorCode: parsing_wstrust_response_failed
Microsoft.Identity.Client.MsalClientException: An error occurred while sending the request.
---> System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
---> System.ComponentModel.Win32Exception: The system cannot contact a domain controller to service the authentication request. Please try again later
According to the team that registered my app in Azure I'm a public client and I've got rights to use 'user.read'
Any idea what could be up so that I can communicate something back to our firm's Azure team. It could be my fault, their fault or MS's fault, I'd just like to know who to complain to. Most of the code is generated by the Azure portal, I just changed the call to AcquireTokenInteractive to AcquireTokenByIntegratedWindowsAuth since my final goal is to silently get the token all the time.
public partial class MainWindow : Window
{
string graphAPIEndpoint = "https://graph.microsoft.com/v1.0/me";
string[] scopes = new string[] { "user.read" };
public MainWindow()
{
InitializeComponent();
}
private async void CallGraphButton_Click(object sender, RoutedEventArgs e)
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
AuthenticationResult authResult = null;
var app = App.PublicClientApp;
ResultText.Text = string.Empty;
TokenInfoText.Text = string.Empty;
var accounts = await app.GetAccountsAsync();
var firstAccount = accounts.FirstOrDefault();
try
{
authResult = await app.AcquireTokenSilent(scopes, firstAccount)
.ExecuteAsync();
}
catch (MsalUiRequiredException ex)
{
System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
try
{
authResult = await app.AcquireTokenByIntegratedWindowsAuth(scopes)
.ExecuteAsync(CancellationToken.None);
}
catch (MsalException msalex)
{
ResultText.Text = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
}
}
public partial class App : Application
{
static App()
{
_clientApp = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority($"{Instance}{Tenant}")
.WithDefaultRedirectUri()
.Build();
TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);
}
private static string ClientId = "<My Client ID>";
private static string Tenant = "<Our Tenant ID>";
private static string Instance = "https://login.microsoftonline.com/";
private static IPublicClientApplication _clientApp ;
public static IPublicClientApplication PublicClientApp { get { return _clientApp; } }
}
Based on https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Integrated-Windows-Authentication, there are a number of constraints surrounding the AcquireTokenByIntegratedWindowsAuth method.
If you are testing with your own user account, consent must be granted to the application for your account. Also, 2FA cannot be enabled when using this Auth flow.
For other users, they will need to consent to the application accessing their account details, or the tenant admin must grant consent across the tenant using the Grant admin consent for Tenant button in the portal.
This flow only applies to "federated users" (e.g. created in AD rather than AzureAD).
This flow is targeted primarily at desktop applications. It only works with .net desktop, .net core and Windows Universal Apps.

B2C reset password

I have following in my startup:
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
// B2C policy identifiers
// public static string SignUpPolicyId = ConfigurationManager.AppSettings["ida:SignUpPolicyId"];
public static string SignInUpPolicyId = ConfigurationManager.AppSettings["ida:SignInUpPolicyId"];
public static string DefaultPolicy = SignInUpPolicyId;
public static string ResetPasswordPolicyId = ConfigurationManager.AppSettings["ida:ResetPasswordPolicyId"];
public static string ProfilePolicyId = ConfigurationManager.AppSettings["ida:UserProfilePolicyId"];
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// Configure OpenID Connect middleware for each policy
app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignInUpPolicyId));
//app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(ResetPasswordPolicyId));
// app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignInPolicyId));
}
private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
notification.HandleResponse();
// Handle the error code that Azure AD B2C throws when trying to reset a password from the login page
// because password reset is not supported by a "sign-up or sign-in policy"
if (notification.ProtocolMessage.ErrorDescription != null && notification.ProtocolMessage.ErrorDescription.Contains("AADB2C90118"))
{
// If the user clicked the reset password link, redirect to the reset password route
notification.Response.Redirect("/Account/ResetPassword");
}
else if (notification.Exception.Message == "access_denied")
{
notification.Response.Redirect("/");
}
else
{
notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
}
return Task.FromResult(0);
}
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
var policy = notification.OwinContext.Get<string>("Policy");
if (!string.IsNullOrEmpty(policy) && !policy.Equals(DefaultPolicy))
{
//notification.ProtocolMessage.Scope = OpenIdConnectScopes.OpenId;
//notification.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken;
notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.Replace(DefaultPolicy, policy);
}
return Task.FromResult(0);
}
private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy)
{
return new OpenIdConnectAuthenticationOptions
{
// For each policy, give OWIN the policy-specific metadata address, and
// set the authentication type to the id of the policy
MetadataAddress = String.Format(aadInstance, tenant, policy),
AuthenticationType = policy,
// These are standard OpenID Connect parameters, with values pulled from web.config
ClientId = clientId,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
},
Scope = "openid",
ResponseType = "id_token",
// This piece is optional - it is used for displaying the user's name in the navigation bar.
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
SaveSigninToken = true //important to save the token in boostrapcontext
}
};
}
}
In my Controller I have following:
public void ResetPassword()
{
// Let the middleware know you are trying to use the reset password
policy (see OnRedirectToIdentityProvider in Startup.Auth.cs)
HttpContext.GetOwinContext().Set("Policy", Startup.ResetPasswordPolicyId);
// Set the page to redirect to after changing passwords
var authenticationProperties = new AuthenticationProperties { RedirectUri = "/" };
HttpContext.GetOwinContext().Authentication.Challenge(authenticationProperties);
}
Right now the reset password just redirect to "/". I am not sure how this works, and havent been able to find any samples. I tried following this sample but it uses some cores libraries and havent succeeded using the documentation.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-web-dotnet-susi
After following Chris suggestion it worked. See image below when clicking reset password.
Follow this Startup.Auth.cs file as closely as possible to get yourself started.
The ConfigureAuth method of the Startup class registers the OWIN OpenID Connect middleware that enables an ASP.NET MVC controller to set the Azure AD B2C policy, to be redirected to, using the OWIN context.
Example:
HttpContext.GetOwinContext().Set("Policy", Startup.ResetPasswordPolicyId);

UWP App - Azure AD Updated Permission Scopes for Single Sign-On JWT Not Triggering Renewed User Consent

Summary:
Our Universal Windows App single-tenant client uses an ASP.NET Web API 2 as a proxy for single-sign on for various Microsoft Office 365 APIs. We use Active Directory for server authentication and the on-behalf-of single sign-on model in our server to exchange tokens for the Office 365 APIs.
Problem:
We have updated a permission scope in Azure for the Office 365 API and the user is not prompted to authorize permission for the new scope, nor is the new scope appearing on NEW tokens. What needs to be done to DETECT and ALLOW our users to authorize new permission scopes?
Additional Details:
Our server is hosted in MSFT Azure App Services. I understand the manifest in Azure is auto-generated and does not need to be manually updated to reflect the updated permission scope?
When the user first logs into the UWP app, they consent to single sign-on permissions associated with the server (eg. Mail.ReadWrite, etc.) which works fine. However, the user consent prompt does not show up again, even after I’ve removed both the client and server apps from my list of consented to apps using
We use the WebTokenRequest and WebAuthenticationCoreManager libraries in the client to get the token for the server. I have also tried using WebAuthenticationBroker (which is not the correct method for our sign-on architecture) and the ADAL library in our client. None of these libraries are prompting for the updated permission.
I have also tried adding wtf.Properties.Add("prompt", "consent"); to our WebTokenRequest to force the user to reapprove permissions. This does not work.
I have also tried restarting the App Service in Azure. This does nothing.
UPDATED 11/10/16:
Following is relevant code I've pulled from our app architecture which may help. Additionally, our server utilizes ADAL version 2.24.304111323.
In our UWP app:
public class AppAuth
{
WebTokenRequestResult result;
WebAccount acc;
async Task<WebTokenRequestResult> GetTokenAsync(WebTokenRequestPromptType promptType = WebTokenRequestPromptType.Default)
{
var wtr = new WebTokenRequest(
provider: "https://login.windows.net",
scope: "",
clientId: appClientId,
promptType: promptType
);
wtr.Properties.Add("authority", "https://login.windows.net");
wtr.Properties.Add("resource", azureWebsiteUrl);
if (promptType != WebTokenRequestPromptType.ForceAuthentication)
{
result = (acc == null) ?
await WebAuthenticationCoreManager.GetTokenSilentlyAsync(wtr) :
await WebAuthenticationCoreManager.GetTokenSilentlyAsync(wtr, acc);
}
if (promptType == WebTokenRequestPromptType.ForceAuthentication ||
result?.ResponseStatus == WebTokenRequestStatus.UserInteractionRequired)
{
result = (acc == null) ?
await WebAuthenticationCoreManager.RequestTokenAsync(wtr) :
await WebAuthenticationCoreManager.RequestTokenAsync(wtr, acc);
}
return result;
}
}
In our server:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters
{
SaveSigninToken = true,
ValidateIssuer = false,
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
}
});
}
}
public class TokenChange
{
protected AdUser _user;
private UserAssertion _assertion;
private static string _aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string _tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string _clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string _appKey = ConfigurationManager.AppSettings["ida:AppKey"];
private string _accessToken;
public AuthenticationResult AuthResult { get; set; }
public AdalException AuthException { get; set; }
private string _emailAddress;
private HttpClient _httpClient;
public bool Authenticate()
{
_accessToken = null;
if (ClaimsPrincipal.Current.Identity.IsAuthenticated)
{
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext
as System.IdentityModel.Tokens.BootstrapContext;
if (bootstrapContext != null)
{
Claim subject = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier);
var upn = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn);
var email = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email);
var userName = upn != null ? upn.Value : email?.Value;
_emailAddress = ClaimsPrincipal.Current.Identity.Name;
var userNameClaim = ClaimsPrincipal.Current.FindFirst("name");
_fullName = userNameClaim != null ? userNameClaim.Value : String.Empty;
_accessToken = bootstrapContext.Token;
_assertion = new UserAssertion(_accessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
}
}
return _accessToken != null;
}
public bool GetAccess(string apiResource)
{
bool gotAccess = false;
AuthResult = null;
AuthException = null;
if (_accessToken != null || Authenticate())
{
ClientCredential clientCred = new ClientCredential(_clientId, _appKey);
string authority = String.Format(CultureInfo.InvariantCulture, _aadInstance, _tenant);
AuthenticationContext authContext = new AuthenticationContext(authority);
bool retry = false;
int retryCount = 0;
do
{
retry = false;
try
{
AuthResult = authContext.AcquireToken(apiResource, clientCred, _assertion);
}
catch (AdalException ex)
{
AuthException = ex;
if (ex.ErrorCode == "temporarily_unavailable")
{
retry = true;
retryCount++;
Thread.Sleep(500);
}
else
{
throw (ex);
}
}
} while ((retry == true) && (retryCount < 1));
if (AuthResult != null && AuthResult.AccessToken != null)
{
gotAccess = true;
}
}
return gotAccess;
}
Based on the description, you were developing an single tenant application which calling the downstream web API(Office 365 API) in your web API.
If you were using the cache to acquire the token in your web API, it will not acquire the new token unless the token is expired. And in this scenario, there is no need to consent/reconsent to update the permission.
Please ensure that you web API is acquire the token from new request instead of cache. If you were using the DbTokenCache, you can clear the cache by deleting the token cache records in PerWebUserCaches table in the database.
Note
In the describing scenario above, since the downstream web API(Office 365 API) get the token using the token issued for your web API which require users sign-in. So only the delegated permission work in the scenario( scp claim in the token instead of roles).

Azure active directory and owin authentication

Just faced an strange issue with azure ad applicationS and owin openid authentication.
To reproduce the issue.
1.create a web app with azure ad authentication in vs 2015 choosing cloud app template .
2.let the standard code be as is.
3.let startup.auth as is.
4.Run the app on local it works fine.
5.now change code in startup àuth as follows
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
public static readonly string Authority = aadInstance + tenantId;
// This is the resource ID of the AAD Graph API. We'll need this to request a token to call the Graph API.
string graphResourceId = "https://graph.windows.net";
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void ConfigureAuth(IAppBuilder app)
{
ApplicationDbContext db = new ApplicationDbContext();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
logger.Debug("SetDefaultSignInAsAuthenticationType called");
//app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider
{
OnResponseSignIn = ctx =>
{
//logger.Debug("OnResponseSignIn called");
////ctx.Identity = TransformClaims(ctx.Identity);
//logger.Debug("TransformClaims called");
}
}
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
logger.Debug("OnResponseSignIn called");
logger.Debug("signedInUserID =" + signedInUserID);
TransformClaims(context.AuthenticationTicket.Identity);
logger.Debug("TransformClaims called");
AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
return Task.FromResult(0);
},
// we use this notification for injecting our custom logic
SecurityTokenValidated = (context) =>
{
logger.Debug("SecurityTokenReceived called");
//TransformClaims(); //pass the identity
return Task.FromResult(0);
},
}
});
}
private static void TransformClaims(System.Security.Claims.ClaimsIdentity identity)
{
if (identity != null && identity.IsAuthenticated == true)
{
var usserobjectid = identity.FindFirst(ConfigHelpers.Azure_ObjectIdClaimType).Value;
((System.Security.Claims.ClaimsIdentity)identity).AddClaim(new System.Security.Claims.Claim("DBID", "999"));
((System.Security.Claims.ClaimsIdentity)identity).AddClaim(new System.Security.Claims.Claim("Super","True"));
}
// return identity;
}
}
6.Run the app on local it will work perfect.
7.Deploy the app on azure websites and the startup àuth owin notification methods will never be called.however app works but identity transformation not
Can somebody help out what's wrong with this is azure ad apps doesn't support cookies or notification not firing or anything wrong with code.
Just to re-assert else than startup.àuth no standard code is changed.
I know this is a bit old, but I had exactly the same issue recently and spent hours trying to understand why it wouldn't work in Azure but it worked absolutely fine in my localhost.
This is basically a configuration issue: in portal.azure.com select your app and then go to settings > authentication / authorisation and make sure that app service authentication is OFF.
It turns out that this setting will take over your startup.auth settings.
I have to give full credit to Vittorio Bertocci as pointed that out to me.

Resources