Reputation: 1137
I've got an implementation of Identity Server 3, where dependent on the URL requested it's possible to have different settings provided to IDS (configured options etc).
This works fine as is, but I am having issues adding MVC controllers/pages to the app (as described https://github.com/IdentityServer/IdentityServer3/issues/1140) - I get a 404 exception when I try to load the new page. If I replace coreApp.Use<IdentityServerWithTenantSwitchingMiddleware>(coreApp.Properties);
with coreApp.UseIdentityServer(new IdentityServerWithTenantSwitchingMiddleware(null, null).GetOptions());
it works as expected, I'm certain the issues comes in my implementation of Invoke
in IdentityServerWithTenantSwitchingMiddleware
.
It seems to me as though I'm missing some bootstrap/setup somewhere that tells IDS that I want to use MVC controllers. Or something. I've seen a couple of similar issues/questions around (https://github.com/IdentityServer/IdentityServer3/issues/1934), but none relate to this exact issue.
I've reproduced this issue using the IdentityServer3 CustomUserService from GitHub - see my fork of CustomUserService demo (specifically IdentityServerWithTenantSwitchingMiddleware.cs and Startup.cs). You can see this issue if you login to the demo (password/username: alice) - it throws an exception trying to render the eula page.
I'll include the important bits of code below:
Startup.cs
public void Configuration(IAppBuilder app)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Trace()
.CreateLogger();
app.Map("/core", coreApp =>
{
coreApp.Use<IdentityServerWithTenantSwitchingMiddleware>(coreApp.Properties);
});
}
IdentityServerWithTenantSwitchingMiddleware
public override Task Invoke(IOwinContext context)
{
var app = new AppBuilder();
//Do some magic based on current request
var options = GetOptions();
_properties.ForEach(kvp =>
{
if (!app.Properties.ContainsKey(kvp.Key))
{
app.Properties.Add(kvp.Key, kvp.Value);
}
});
app.UseIdentityServer(options);
return app.Build()(context.Environment);
}
private IdentityServerOptions GetOptions()
{
var factory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get());
// different examples of custom user services
var userService = new EulaAtLoginUserService();
// note: for the sample this registration is a singletone (not what you want in production probably)
factory.UserService = new Registration<IUserService>(resolver => userService);
var options = new IdentityServerOptions
{
SiteName = "IdentityServer3 - CustomUserService",
SigningCertificate = Certificate.Get(),
Factory = factory,
AuthenticationOptions = new AuthenticationOptions
{
LoginPageLinks = new LoginPageLink[] {
new LoginPageLink{
Text = "Register",
Href = "localregistration"
}
}
},
EventsOptions = new EventsOptions
{
RaiseSuccessEvents = true,
RaiseErrorEvents = true,
RaiseFailureEvents = true,
RaiseInformationEvents = true
}
};
return options;
}
Any/all help/suggestions appreciated.
Alex
Upvotes: 0
Views: 606
Reputation: 1137
Have found an answer to my issue.
Taken from https://github.com/damianh/DynamicKatanaPipeline - it looks as though I was not running the next steps in the pipeline. Working code here, in case it helps anyone:
public override Task Invoke(IOwinContext context)
{
var app = ConfigurePipeline(context);
var dynamicAppFunc = app.Build();
return dynamicAppFunc(context.Environment);
}
private IAppBuilder ConfigurePipeline(IOwinContext context)
{
var app = new AppBuilder();
app.UseIdentityServer(GetOptions(context));
app.Run(_next.Invoke);
return app;
}
Upvotes: 0