Published Web App Getting AADSTS50011 Error - asp.net

Trying to fix this Azure Active Directory issue. I have an ASP.Net 4.7 website. It correctly takes me to the SSO page and confirms my identity. However, upon taking me back to my site, I get the message:
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: 'MyApplication-ClientID'.
It makes sense that the AD App Registration's | Authentication | Redirect URI does not match what I am sending it. However, as near as I can tell, they do.
Here is my code in the Startup.cs file:
public void Configuration(IAppBuilder app) {
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions {
ClientId = clientId, // MyApplication-ClientID
Authority = authority, // https://login.microsoftonline.com/MyDirectory-TenantID/v2.0
RedirectUri = redirectUri, // https://MySiteName.azurewebsites.net
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.IdToken,
TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications {
AuthenticationFailed = OnAuthenticationFailed
}
}
);
}
Here are the settings in my Web.config file:
<add key="ClientId" value="MyApplication-ClientID" />
<add key="Tenant" value="common" />
<add key="Authority" value="https://login.microsoftonline.com/MyDirectory-TenantID/v2.0" />
<add key="RedirectUri" value="https://MySiteName.azurewebsites.net" />
Both the Redirect URI and the Configs RedirectUri are: https://MySiteName.azurewebsites.net
Here is the initial request when I am asked to select an account when trying to log in:
https://login.microsoftonline.com/MyDirectory-TenantID/oauth2/v2.0/authorize
?response_type=code+id_token
&redirect_uri=https%3A%2F%2FMySiteName.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback
&client_id=MyApplication-ClientID
&scope=openid+profile+email
&response_mode=form_post
&nonce=3f63a75d79af449082801c5183d5fbdb_20200710145808
&state=redir%3D%252F
So I see the redirect_uri seems to add the /.auth/login/aad/callback to the end of what I told it to be. So I updated the AD App Registration's | Authentication | Redirect URI to match and instead of the above error I get the following error:
The page cannot be displayed because an internal server error has occurred.
I am just at a loss here trying to figure out what is mismatched or perhaps just missing.

Related

Why is the Authorization code not automatically redeeming? - Automatic code redemption in OODC - Authorization Code Flow with Azure AD - c# aspnet 4.8

I am trying to get gain an Access Token after receiving the authorisation token via postback from Azure.
I simply serve the Home view where there is a button to logon to Azure. Initially i followed this post: https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp but then tried to modify the code to follow the Authorisation Code Flow.
Strangely it was working nicely (after googling for days) when hosted on IIS Express but when moving to local IIS I am only able to complete half the flow. I wonder if it's significant that my app is running as an Application on IIS not as a website? The address is https://localhost/testapp. My site on IIS runs on port 80 and 443 as standard. IIS is as per (apologies for the heavy redaction):
In essence the code redemption is not taking place.
Here is my owin Startup.cs:
string clientId = ConfigurationManager.AppSettings["ClientId"];
string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
string redirectUri = ConfigurationManager.AppSettings["RedirectUri"];
static string tenant = ConfigurationManager.AppSettings["Tenant"];
string authority = string.Format(System.Globalization.CultureInfo.InvariantCulture, ConfigurationManager.AppSettings["Authority"], tenant);
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Sets the ClientId, authority, RedirectUri as obtained from web.config
ClientId = clientId,
ClientSecret = clientSecret,
Authority = authority,
RedirectUri = redirectUri, //struggling to see the difference between RedirectUri and CallbackPath
CallbackPath = new PathString("/home/"), // do i need this as well?
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
RedeemCode = true,
ResponseMode = OpenIdConnectResponseMode.FormPost, // do i need this?
SaveTokens = true, // do i need this?
UsePkce = true, // default is true
ResponseType = OpenIdConnectResponseType.Code,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed,
},
}
);
}
My home controller is simply:
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
public void SignIn()
{
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = "/" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
[AllowAnonymous]
public void SignOut()
{
HttpContext.GetOwinContext().Authentication.SignOut(
OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
}
}
web.config:
<add key="ClientId" value="xxxxxxxxxxxx" />
<add key="ClientSecret" value="xxxxxxxxxxxx" />
<add key="redirectUri" value="https://localhost/testapp/home/" />
<add key="Tenant" value="xxxxxxxxxxxx" />
<add key="Authority" value="https://login.microsoftonline.com/{0}/v2.0" />
On Azure the Redirect URI is:
this is the trace from fiddler:
You can see from the trace that there is not further call to the token endpoint even though I believe I have the correct configuration for OWIN to make the call automatically?
I am really stumped and I would appreciate some help please.

Dotnet Framework Azure AD connected service

I am trying to get Azure AD connected service working for my dotnet framework applications. I went through the wizard and it added the necessary dependencies and files I need for it to work. The issue I am having is it does not reliably work. So I've rolled back and I am just working locally. If I type in localhost/Athena it does not work, however, it leaves /signin-oidc at the end of the URL. When I manually delete that last part the page works fine. The error I am getting is
IDX21323: RequireNonce is 'System.Boolean'.
OpenIdConnectProtocolValidationContext.Nonce was null.
If I type in https://localhost/Athena it works every time. Below is the code from my Startup.Auth.cs file.
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = "8675309",
Authority = authority,
CallbackPath = new PathString("/signin-oidc"),
//Tried with the below redirecturi and I still have the same issues.
//RedirectUri = "https://localhost/Athena/signin-oidc"
});
}
This exception is occured when an OpenIdConnect middleware encounters an invalid nonce or a missing nonce cookie.
Try making following configurations.
Configure startup.cs as below
AuthenticationType = “ApplicationCookie”,
CookieSameSite = SameSiteMode.None,
CookieSecure = CookieSecureOption.Always
Check/configure web.config:
<system.web>
<sessionState cookieSameSite=”None”/>
<httpCookies requireSSL=”true” />
</system.web>
note:Make sure all your website traffic is over https.
The initialization code is different depending on the platform. For ASP.NET Core and ASP.NET, signing in users is delegated to the OpenID Connect middleware. Some configuration is required to adapt them to the Microsoft identity platform.
The code related to authentication in an ASP.NET web app and web APIs is located in the App_Start/Startup.Auth.cs file.
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Authority` represents the identity platform endpoint - https://login.microsoftonline.com/common/v2.0.
// `Scope` describes the initial permissions that your app will need.
// See https://azure.microsoft.com/documentation/articles/active-directory-v2-scopes/.
ClientId = clientId,
Authority = String.Format(CultureInfo.InvariantCulture, aadInstance, "common", "/v2.0"),
RedirectUri = redirectUri,
Scope = "openid profile",
PostLogoutRedirectUri = redirectUri,
});
}
You can refer the following document to know detailed information
/configuration in web.config file related to above Startup.auth.cs configuration
https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-sign-user-app-configuration?tabs=aspnet
The Microsoft identity platform implementation of OpenID Connect has
a few well-defined scopes .You can refer this
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent
to know scopes and permissions in microsoft identity platform

Is it possible to setup webform site to use windows authentication and azure ad authentication in the same time

Is it possible to setup a webform site to use windows authentication and azure ad authentication at the same time?
We have an old asp.net webform site. We used windows authentication on it. We added the possibility to authenticate a user by Azure AD (we used OWIN). The problem is we can setup only one type of authentication: windows or OWIN(azure ad), but we need both.
In the web.config I added:
<authentication mode="Forms">
<forms name="ccs_auth" loginUrl="sso.aspx" protection="All" path="/" timeout="45" cookieless="UseCookies"/>
</authentication>
<location path="sso.aspx">
<system.web>
<authorization>
<allow users="?,*" />
</authorization>
</system.web>
</location>
In the IIS I allowed "windows authentication" and "forms authentication" for sso.aspx page. My idea is: when the user redirected to sso.aspx I get a login name from System.Web.HttpContext.Current.Request.ServerVariables["LOGON_USER"], then check this name in active directory, then try to find a user in our database. If the user not found, starts azure active directory authentication, if authenticated, we try to find a user in the database by Azure AD claim.
My code in Startup.cs :
public void Configuration(IAppBuilder app)
{
if (useAzureAd)
{
app.SetDefaultSignInAsAuthenticationType("ApplicationCookie");
//app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/sso.aspx"),
CookieSecure = CookieSecureOption.SameAsRequest
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Sets the ClientId, authority, RedirectUri as obtained from web.config
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
// ResponseType is set to request the id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseType.IdToken,
// ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
// To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
// To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false
},
// OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
});
}
}
In result I get an exception:
HTTP Error 404.15 - Not Found
The request filtering module is configured to deny a request where the query string is too long.
Look like my request is infinite redirects to the sso.aspx:
Requested URL
http://localhost:80/AzureAdWebForm/SSO.aspx?ReturnUrl=%2FAzureAdWebForm%2FSSO.aspx%3FReturnUrl%3D%252FAzureAdWebForm%252FSSO.aspx%253FReturnUrl%253D%25252FAzureAdWebForm%25252FSSO.aspx%25253FReturnUrl%25253D%2525252FAzureAdWebForm%2525252FSSO.aspx%2525253FReturnUrl%2525253D%252525252FAzureAdWebForm%252525252FSSO.aspx%252525253FReturnUrl%252525253D%25252525252FAzureAdWebForm%25252525252FSSO.aspx%25252525253FReturnUrl%25252525253D%2525252525252FAzureAdWebForm%2525252525252FSSO.aspx........................
If I set useAzureAd = false, windows authentication works correctly.
If I set useAzureAd = true and remove <authentication mode="Forms"> from config - Azure AD works correct
Where is my mistake? Is it possible to use both: windows authentication and Azure Ad in the webform web site?

Getting claims with azure ad using wsfedration and Owin middleware

I'm trying to add authentication option to support Azure AD in an asp.net application. The web.config file has some options:
<add key="ida:FederationMetadataLocation" value="https://login.microsoftonline.com/common/FederationMetadata/2007-06/FederationMetadata.xml" />
<add key="ida:Realm" value="..." />
<add key="ida:LogoutReply" value="..." />
<add key="ida:OwinWsFederationEnabled" value="true" />
In addition, the authentication is configured in code like this:
public partial class Startup{
public void ConfigureAuth(IAppBuilder app){
app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(...),
LogoutPath = new PathString(...),
});
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ExternalCookie",
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
});
var authenticationOptions = new WsFederationAuthenticationOptions()
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
MetadataAddress = metadata,
Wtrealm = realm,
Wreply = reply,
Caption = caption,
SignOutWreply = logoutreply,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false
}
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
};
app.UseWsFederationAuthentication(authenticationOptions);
}
}
This kind of works, because it redirects me to azure login and back to the app login path. But there, when all is supposed to be ok, I'm not getting any information about the newly logged in user.
var oid = GetClaim("http://schemas.microsoft.com/identity/claims/objectidentifier");
with this or any other claim type, for that matter. All the claims are returning null-values.
The app is registered to my Azure AD directory as multitenant.
If I set the metadatalocation to be the tenant specific metadata, the AAD won't redirect me back to the application as the azure ad user is from another tenant.
What am I missing here to get the user claims from Azure AD?

Owin / Mvc add support for bearer token authentication

My objective is to have an Asp.Net Mvc action secured with OpenId authentication, and support 2 types of clients: browser and a native WPF application. The STS I will use is ADFS 2016.
Currently clients browsers works well. For this, I have UseOpenIdConnectAuthentication configured in my startup class.
I'm able to call my Mvc action (secured with Authorize attribute), user is redirected to STS, and once authentication is done, I come back to my Mvc action with a ClaimsIdentity properly filled.
Now I'm trying to have a native WPF app able to authenticate to the same Mvc action in the same Web app, and things are getting tricky.
On the client side (my WPF application), I'm using ADAL and the following code:
var authContext = new AuthenticationContext("<MySTSUri>");
var authResult = await authContext.AcquireTokenAsync(
"http://localhost:1276/openid/login",
"MyNativeAppId",
new Uri("myapp://openid"),
new PlatformParameters(PromptBehavior.Auto),
UserIdentifier.AnyUser,
"");
if (!string.IsNullOrEmpty(authResult.AccessToken))
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(authResult.AccessTokenType, authResult.AccessToken);
HttpResponseMessage response = await httpClient.GetAsync("http://localhost:1276/openid/login");
if (response.IsSuccessStatusCode)
{
var text = await response.Content.ReadAsStringAsync();
}
}
}
The problem is basically that I can't tell the Web app to be able to validate this type of ADAL request.
I've tried various things in the Web application Owin startup file configuration:
leaves UseOpenIdConnectAuthentication: it doesn't seem sufficient, I'm redirected to STS with the ClientId of the Web application
UseActiveDirectoryFederationServicesBearerAuthentication api since I know my STS will always be an ADFS
UseOAuthBearerAuthentication
None of them are working.
Please can someone help how to achieve this?
Am I going in the right direction?
Any ideas/pointers would be greatly appreciated.
Thanks,
Alex
I've managed to get it working. I post the answer for the record.
What helped me a lot is to enable Owin logs in the web.config:
<system.diagnostics>
<switches>
<add name="Microsoft.Owin" value="Verbose" />
</switches>
</system.diagnostics>
Then with Owin, you can simply chain multiple authentication methods. So in my case, I've just used:
app.UseActiveDirectoryFederationServicesBearerAuthentication(
new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
MetadataEndpoint = adfsMetadataEndpoint,
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudiences = new[] { validAudience }
}
});
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
AuthenticationType = "OpenId",
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
ResponseType = OpenIdConnectResponseTypes.CodeIdToken,
Scope = "openid",
SignInAsAuthenticationType = "Cookies"
});
Cheers,
Alex

Resources