简体   繁体   中英

IdentityServer3 Custom OWIN Middleware with additional MVC controllers

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

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM