Here is my Configure method from my Startup class.
public void Configure(IApplicationBuilder app)
{
// Setup configuration sources
var configuration = new Configuration();
configuration.AddJsonFile("config.json");
configuration.AddEnvironmentVariables();
// Set up application services
app.UseServices(services =>
{
// Add EF services to the services container
services.AddEntityFramework()
.AddSqlServer();
// Configure DbContext
services.SetupOptions<DbContextOptions>(options =>
{
options.UseSqlServer(configuration.Get("Data:DefaultConnection:ConnectionString"));
});
// Add Identity services to the services container
services.AddIdentitySqlServer<ApplicationDbContext, ApplicationUser>()
.AddAuthentication();
// Add MVC services to the services container
services.AddMvc();
});
// Enable Browser Link support
app.UseBrowserLink();
// Add static files to the request pipeline
app.UseStaticFiles();
// Add cookie-based authentication to the request pipeline
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = ClaimsIdentityOptions.DefaultAuthenticationType,
LoginPath = new PathString("/Account/Login"),
});
// Add MVC to the request pipeline
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
routes.MapRoute(
name: "api",
template: "{controller}/{id?}");
});
}
Where can I access the HttpConfiguration instance, so that I could set the CamelCasePropertyNamesContractResolver, just like I did in WebApi 2:
var formatterSettings = config.Formatters.JsonFormatter.SerializerSettings;
formatterSettings.Formatting = Formatting.None;
formatterSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Replace services.AddMvc(); with the following.
services.AddMvc().SetupOptions<MvcOptions>(options =>
{
int position = options.OutputFormatters.FindIndex(f =>
f.Instance is JsonOutputFormatter);
var settings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var formatter = new JsonOutputFormatter(settings, false);
options.OutputFormatters.Insert(position, formatter);
});
UPDATE
With the current version of ASP.NET, this should do.
services.AddMvc().Configure<MvcOptions>(options =>
{
options.OutputFormatters
.Where(f => f.Instance is JsonOutputFormatter)
.Select(f => f.Instance as JsonOutputFormatter)
.First()
.SerializerSettings
.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
UPDATE 2
With ASP.NET 5 beta5, which is shipped with Visual Studio 2015 RTM, the following code works
services.AddMvc().Configure<MvcOptions>(options =>
{
options.OutputFormatters.OfType<JsonOutputFormatter>()
.First()
.SerializerSettings
.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
UPDATE 3
With ASP.NET 5 beta7, the following code works
services.AddMvc().AddJsonOptions(opt =>
{
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
RC2 UPDATE
MVC now serializes JSON with camel case names by default. See this announcement.
https://github.com/aspnet/Announcements/issues/194
The Configure function was removed from services.AddMvc() in either Beta 6 or 7. For Beta 7, in Startup.cs, add the following to the ConfigureServices function:
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
});
Use below setting to avoid lowercase replacement for .net core
services.AddMvc().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
Related
I have a small Blazor WASM project that I recently migrated to .net 6. But now I tried to run the published project and the application warned me that I don't have a license for Duende Identity Server.
My question is:
Can I do without the Duende Identity Server?
In my application, I need user login and role assignment. I want to have users defined only for this application and I want to use the application database to store them.
My Program.cs looks like this:
var builder = WebApplication.CreateBuilder(args);
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
var appDbConStr = builder.Configuration.GetConnectionString("AppDbConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(appDbConStr));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddClaimsPrincipalFactory<AppClaimsPrincipalFactory>();
builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, AppDbContext>(opt =>
{
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Role);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Role);
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Avatar);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Avatar);
opt.IdentityResources["openid"].UserClaims.Add(UserClaim.Nick);
opt.ApiResources.Single().UserClaims.Add(UserClaim.Nick);
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
builder.Services.AddAuthentication().AddIdentityServerJwt();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<IRazorRendererHelper, RazorRendererHelper>();
builder.Services.AddScoped<Vks.Server.Services.SerialGenerator>();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
Thank you
Use default ASP.NET CORE Identity (do not add reference to Duende).
Must read article covers all features of ASP.NET CORE Identity
https://chsakell.com/2018/04/28/asp-net-core-identity-series-getting-started/
Remove Duende reference by deleting reference on Microsoft.AspNetCore.ApiAuthorization.IdentityServer (duende is sub referenced)
Add asp.net core identity as follow:
builder.Services
.AddIdentity<ApplicationUser<int>, ApplicationRole>(config =>
{
config.SignIn.RequireConfirmedEmail = false;
config.Lockout.AllowedForNewUsers = true;
config.Lockout.MaxFailedAccessAttempts = 3;
config.User.RequireUniqueEmail = true;
config.Password.RequiredLength = 8;
//...other opts//
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserManager<CustomUserManager>() // inherited from UserManager with overriden logic
.AddDefaultTokenProviders()
.AddTokenProvider<CustomAuthenticatorTokenProvider>(TokenOptions.DefaultAuthenticatorProvider) // inherited from AuthenticatorTokenProvider with overriden logic
.AddPasswordValidator<CustomPasswordValidator>(); // implements IPasswordValidator for additional password validation
Trying to implement firebase google authentication in the swagger
onboard: asp.net core 5, Swashbuckle.AspNetCore 6.3.1,
In fairbase console > authentication > Sign-in method > authentication via google is enabled
On ServiceConfigure method:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyApi", Version = "v1" });
c.UseInlineDefinitionsForEnums();
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
//email and password authentication - works fine
Password = new OpenApiOAuthFlow
{
TokenUrl = new Uri("/api/v1/auth/password", UriKind.Relative), //here my backend endpoint
Extensions = new Dictionary<string, IOpenApiExtension>
{
{ "returnSecureToken", new OpenApiBoolean(true) },
},
},
//try add google auth - troble here
Implicit = new OpenApiOAuthFlow()
{
//Not sure about the endpoints. Its not work with 404 err
AuthorizationUrl = new Uri("https://securetoken.google.com/MY-PROJECT-FIREBASE-NAME"),
TokenUrl = new Uri("https://securetoken.google.com/MY-PROJECT-FIREBASE-NAME"),
Scopes = new Dictionary<string, string>
{
{ "profile", "profile" },
}
}
}
});
c.OperationFilter<AuthorizeCheckOperationFilter>();
});
class filter:
public class AuthorizeCheckOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var requiredScopes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
.OfType<AuthorizeAttribute>()
.Select(attr => attr.Policy)
.Distinct();
if (requiredScopes.Any())
{
var oAuthScheme = new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
};
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement
{
[ oAuthScheme ] = requiredScopes.ToList()
}
};
}
}
}
in Configure method:
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyApi v1");
What endpoints for AuthorizationUrl / TokenUrl should call?
Any additinal options for swagger?
I`m new in Firebase. M.b. need aditional adjustments in firebase console?
I would be very appreciate for a code sample.
I found a good repo for you. This simple is .NET 5 WebApi project base with the following features implemented:
Swagger with Firebase login
Serilog Logging to Amazon CloudWatch
Encrypted fields in AppSettings
Soft Delete and Audit Columns
Multitenancy support
Data Seeding
Localization
code sample:clean-base-api
I am working on a blazor application where I used my API project as Identity
Provider. Everything is working fine but the issue is that the access token
issued by my API is not validated by the API. It turns out the API is expecting a
cookie header. I took a closer look at blazor hosted application and found out
the cookie is being sent along with each request but it's same-origin.
My Blazor WASM project does not automatically attach this cookie in the request
header, just the access token.
Is there a way I can make the Http handler attach this cookie on each request?
or make the API validate the access token instead of the identity cookie.
This is my startup class in the API Project
public static void AddIdentityServer(IServiceCollection services,IConfiguration configuration)
{
services.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/Identity/Account/Login";
options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
}).AddProfileService<LocalProfileService>()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(option =>
{
option.Clients.Add(new Client
{
ClientId = "blazor",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedCorsOrigins = { "https://localhost:5001" },
AllowedScopes = { "openid", "profile", "email","id" },
RedirectUris = { "https://localhost:5001/authentication/login-callback" },
PostLogoutRedirectUris = { "https://localhost:5001/" },
Enabled = true,
RequireConsent = false,
});
option.IdentityResources.AddEmail();
option.IdentityResources["openid"].UserClaims.Add("name");
option.ApiResources.Single().UserClaims.Add("name");
option.IdentityResources["openid"].UserClaims.Add("role");
option.ApiResources.Single().UserClaims.Add("role");
option.IdentityResources.Add(new IdentityResource("id",new string[] {"id" }));
option.ApiResources.Single().UserClaims.Add("id");
});
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = configuration["ExternalLoginApiKey:GoogleClientId"];
options.ClientSecret = configuration["ExternalLoginApiKey:GoogleClientSecret"];
})
.AddFacebook("Facebook", options =>
{
options.AppId = configuration["ExternalLoginApiKey:FacebookAppId"];
options.AppSecret = configuration["ExternalLoginApiKey:FacebookAppSecret"];
})
.AddIdentityServerJwt();
}
Program class in the Blazor Project
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
builder.Services.AddHttpClient<IAuthorizedRestService, AuthorizedRestService>(
client => client.BaseAddress = new Uri("https://localhost:5002/api/mart/v1/"))
.AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
.ConfigureHandler(authorizedUrls: new[] { "https://localhost:5002" }));
builder.Services.AddHttpClient("noauth", option => option.BaseAddress = new
Uri("https://localhost:5002/api/mart/v1/"));
builder.Services.AddScoped<IRestService, RestService>();
await builder.Build().RunAsync();
}
I have found the Solution.
It happens that there is already a JWT handler provided by IdentityServer4 for APIs that double as Authorization Server
.AddIdentityServerJwt();
So what I did was to configure it
services.Configure<JwtBearerOptions>
(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.Authority = "https://localhost:5002";
options.Audience = "mart";
options.SaveToken = true;
});
Then specify the Authentication scheme to use
[Authorize(AuthenticationSchemes = IdentityServerJwtConstants.IdentityServerJwtBearerScheme)]
You can also add it globally in the start up class
var authorizationPolicy = new AuthorizationPolicyBuilder(IdentityServerJwtConstants.IdentityServerJwtBearerScheme)
.RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
You can read more using these links
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.1
I try to use AAD authentification on my WebApi (dotnet core 3.1) from swagger (Swashbuckle) client.
In my Startup class, I've configured like follow:
// Configure authentication
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
my settings for AzureAd:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "xxxx-xxxxx1b",
"Domain": "myoffice.onmicrosoft.com",
"TenantId": "xxxxx-xxxxa5",
"Scope": "api://xxxxxxxx-abc3cff48f1b/Full.Access",
"ScopeDescription": "Full Access"
},
...
services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.OAuth2,
In = ParameterLocation.Header,
Flows = new OpenApiOAuthFlows()
{
Implicit = new OpenApiOAuthFlow
{
TokenUrl = new Uri($"Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/token"),
AuthorizationUrl = new Uri($"{Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}/oauth2/v2.0/authorize"),
Scopes =
{
{
Configuration["AzureAd:Scope"],Configuration["AzureAd:ScopeDescription"]
}
}
}
}
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
And in my Configure method:
app.UseSwaggerUI(c =>
{
c.RoutePrefix = string.Empty;
c.SwaggerEndpoint($"/swagger/{ApiVersion}/swagger.json", ApiName);
c.OAuthClientId(Configuration["AzureAd:ClientId"]);
c.OAuthScopeSeparator(" ");
});
Swagger corectly log to AAD using my credential and when I use a route protected by [Authorize] the token is correcly sent to the API by I receive a 401 error with the following message:
www-authenticate: Bearer error="invalid_token"error_description="The issuer 'https://login.microsoftonline.com/{tenantid}/v2.0' is invalid"
The url https://login.microsoftonline.com/{tenantid}/v2.0 is in the token in the iss section.
What is wrong?
According to your error and your code, you do not tell your application the ValidIssuer. So you get the error. Please add the following code in the method ConfigureServices of startup.cs file
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuers = new[] {
},
});
For example
Configure Azure AD for your web API. For more details, please refer to the document
a. Create Azure AD web api application
b. Expose API
c. Configure code
config file
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Client_id-of-web-api-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",
"TenantId": "<your tenant id>"
},
Add following code in the Stratup.cs
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.Authority += "/v2.0";
options.TokenValidationParameters = new TokenValidationParameters
{
/**
* with the single-tenant application, you can configure your issuers
* with the multiple-tenant application, please set ValidateIssuer as false to disable issuer validation
*/
ValidIssuers = new[] {
$"https://sts.windows.net/{Configuration["AzureAD:TenantId"]}/",
$"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/v2.0"
},
ValidAudiences = new[]
{
options.Audience,
$"api://{options.Audience}"
}
};
});
Configure swagger. For more details, please refer to the blog.
a. Create Azure Web application
b. Configure API permissions. Regarding how to configure, you can refer to the document
c. code
Install SDK
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
config file
"Swagger": {
"ClientId": ""
},
Add the following code to Startup.cs in the ConfigureServices method:
services.AddSwaggerGen(o =>
{
// Setup our document's basic info
o.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Protected Api",
Version = "1.0"
});
// Define that the API requires OAuth 2 tokens
o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
Implicit = new OpenApiOAuthFlow
{
Scopes = new Dictionary<string, string>
{
{ "api://872ebcec-c24a-4399-835a-201cdaf7d68b/user_impersonation","allow user to access api"}
},
AuthorizationUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/authorize"),
TokenUrl = new Uri($"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/v2.0/token")
}
}
});
o.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "oauth2",
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
});
Add the following code to the Configure method:
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.OAuthClientId(Configuration["Swagger:ClientId"]);
c.OAuthScopeSeparator(" ");
c.OAuthAppName("Protected Api");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
Test
I am attempting to learn how to use WS-Federation in a .NET Core application. I am attempting a basic step of having my client application redirect to an authentication service (defined in my FederationMetadata.xml file), but when I attempt to access a controller requiring authentication [url in this case is http://localhost/STSAwareApp/Test], my redirect url becomes too large to be usable (I get a 404.15, query string is too large).
Since I'm new to WS-Federation, I'm assuming that I have a configuration issue in my startup:
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
services.AddControllersWithViews();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddWsFederation(authenticationScheme: "WsFederation", displayName: "Test WS-Fed", options =>
{
options.Wtrealm = "http://localhost/STSAwareApp/Test";
options.MetadataAddress = "http://localhost/STSAwareApp/files/FederationMetadata.xml";
options.RequireHttpsMetadata = false;
}).AddCookie(options =>
{
options.Cookie.Name = "TestStsAuth";
options.Cookie.HttpOnly = true;
});
services.AddLogging(
builder =>
{
builder.AddFilter("Microsoft", LogLevel.Trace)
.AddFilter("System", LogLevel.Trace)
.AddConsole();
});
}
}
Here is an example of the redirect URL that is getting generated (just for completeness sake):
http://localhost:80/STSAwareApp/Test?wtrealm=http%3A%2F%2Flocalhost%2FSTSAwareApp%2FTest&wa=wsignin1.0&wreply=http%3A%2F%2Flocalhost%2FSTSAwareApp%2Fsignin-wsfed&wctx=CfDJ8O7dpxEY6MBCgxct4kkpp1gFIwYvsJN7p6zOuAiyltKmCqff605h1uCh7ZBNM6WneU_7XlxHKAt7CYmBdXG_e19L8z-p64d21gJjDJCdjOkfNieQWNRSPQPGZDUL8eBEVqs4vWaKN-sof8lnblDbySiP8NJPR945c8IYqRwaf7ZBZ-_IxoWZLN_OgMOgFnU5XjtDeUfFCcHh0dtGwSc4PVDPxhKIpxb3JyIEMBRA19qZpudqQEylX6WHek5LkNK1IDbWDv2ll9F5HCJSQxvpVDrLw62dBfF6IDNg3Ar8q2Yr_bpV1gA1RR7kHp3Gs4soxfZENfvi96qkPJs4ZOqvUYjRQjho34Lkc9VH5q2w7n4Oty6abFXs_jeDQQN7ZyFBGQrb-wxBZBEuvNJAFp-ckhGVCeKrtdmXS4bVAvbEtPAEtLHXJpv82Y843_UVCeAQycMjmz2stIovI-HiKAWwCkoc03J7gOlTEwyrn1cR-Ia3QWN4mPN2ncqxW5e80kamNDIDmRxiWoox1Z6x5SATSIO3KergXc7VE1G8-2gLicc8_flyLR6NXUAdDRZTnxGzChHzf2L1eqjm0K_PvioAdqJNuFDlFMeGyfarEbXahAqpchuDvSgolSEKgGO-uLw5GEdCS-5cX_Ztt3bAjbXzkPMdhzYbXFWTDdYTMMMta18nhzgAk5CIzDvo1BmniWGdwUy-lAWm9BoNd4TsroQa-F8NJ86K4sixQIqRqQ-D-Bf_672hHbIkY1QEEe8tqTH-1Qwn9K5RY5sVFQLu0Ec4bp0Zj2EDis-GAtMxhp6761MciYjjhqgORhe3gsLeej5GEY0AErXUOCxdghQKs-waLQtNQ2F4Xn226DYp6NVn8bLs5pu4mFblaWRn9cVzKPHUosRT9BjKqbnLpCCC0A4cOXec-G5znWLOXa6G4qsZjFl5h79MwStDnzP6GU2Wg6TaLG83783f6bRsJwX8blc1CMEjByphkpZp-VdR6FytLXvu4bh8gQQo2K3ad76pNlF8HnA4y1f0p86A82i2IPPDrOeW6YFupzZRITSFz-JvhjAZbkSzu26bgqgHNVTIz1ebu9mHIMQzGzpAu0rFIl16HszR7Omxn8TljADTCCLasQyLNRUIXSA5teeowULetXEv_rmOr6ANkk0kQ-q3pPuiOzkA0aFV6g1jYQ-JvS9K817IafEes7akoDrPbeHEmvD5sWzxERlMtnEQtYwcrPiOroWXIh1QgLjqUgTxtagWmkzoBWVM5PnNmMVkk0alyTgZKOomTcZN8ePkLRp4sY0d0D_uqb0Rn_s757Nb-oDztAz6SLOkCzWnPDif3eIAFTZy24v_oYr3SOFfvM2J-_t0kg3zlRovg25_bPPSs-qyfrMMBSbMammB5e7SKbIna4dPhMdv93Vm6I2GwJ8-VY-pAuBT4MQXPLD1VwdiBT3hWsZOoeMUl1JuL7B9pJDAMBNO2OUTaRb7dajP3VsA09XSgVrBeZ1Hvk733TrzFVoR5KQgHS4qw9cxquRmqP2XfEYTQocB-mUL4b-n0h3RN2qzaHn_VH2pZDV842YcanF4SZ8dDPB4EnLCWU7pf67IwvruInvu8MXg01xNoURh6rKLmSwikbgsEM7Es87RMQSEvar1QixBId9XMO1YiHVvGAdJoivUveJSO1T8Aj4A2xFllBjtD4SfnJc5UDTQ7UxGnVmIVw6pwS9N26U_u09n-T4j5R-ZVQyCNgSjoNRg-3jmMatXcAhT4vJgO-kRuzMiBKnavJ7EPyS8Th8KUK0ws1tQYQKmQQGvd7DT_GRC0wXT8HrTZ1uxTmxxDibzyCLxJZmulLHPcYaXwpWw6j56vOxgCrGy-3L5GtfnXNN1UdE3QzbE6_XL3xF8B3uD6Z5g5ZB_ZR4Q0QS0K9Kb6guaAtxEJYKc2eE2DZ2OpMNtyw5imNYt9crd5J4mB05GR7c0Nur2vqzk1mGM56_0IQD9L4HV4fXNmQuprEpwNZ41NyW-bhcVS30rZn73WLc-XBlNWhCrE_HiTWzCDOn9juofX7_C2AcQypJt-aweXEN5uxRWPp_W9qFJNblrkjzAEr3o7_dylYLYTstOvW4dYuIE4WlTUiJdJF3Iy02whGQUpclOINsxZ3wotkKY2JsnUzsolSeIfWe-es8soGOkPnDSthgjRbpTxltmVz10L0kAo4zckz4HvhEmziWPsGWZH1UVtRKLniT60qq9PPxeuu_dsodov-ByanyRwMHlkzCJhmSBDE0
I'm under the assumption that the url is not only incorrect because the wctx is too long, but it should be attempting to redirect to a different service [http://localhost/STS/V1], it is attempting to the original url with the federation parameters in the query string. I think that the wctx should be smaller, because even if I increase the size of my URL limits, it just continues to grow.
The issue with this was that the FederationMetadata.xml document was not configured correctly. Not exactly sure what was wrong, but instead of attempting to have a valid xml document, it was simpler to update the Configuration property of the WsFederationOptions. Attached is the updated Startup call:
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
services.AddControllersWithViews();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddWsFederation(authenticationScheme: "WsFederation", displayName: "Test WS-Fed", options =>
{
WsFederationConfiguration configuration = new WsFederationConfiguration();
configuration.TokenEndpoint = "http://localhost/STSSpike/V1";
options.Configuration = configuration;
options.Wtrealm = "http://localhost/STSAwareApp/Test";
}).AddCookie(options =>
{
options.Cookie.Name = "TestStsAuth";
options.Cookie.HttpOnly = true;
});
services.AddLogging(
builder =>
{
builder.AddFilter("Microsoft", LogLevel.Trace)
.AddFilter("System", LogLevel.Trace)
.AddConsole();
});
}
Guessing that this is a pretty localized issue, so might want to close.