Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
613 views
in Technique[技术] by (71.8m points)

openid connect - Aspnet Core 3.1 MVC Razor pages gets 302 after authenticating with Identity Server 4 OpenIdConnect

I have an MVC Razor pages app which I want to hook into our Identity Server Implementation. We have followed the tutorial in their quickstart https://identityserver4.readthedocs.io/en/latest/quickstarts/2_interactive_aspnetcore.html and got it working in a brand new project, so we assume the client and IDS configuration is OK.

However, when we port it into our RazorPages application we get into a loop. We are sent off to the IDS, we log in and we're sent back to the signin-oidc page. This page seems to generate a 302.

Please see this network trace. Each time the request is made a new "code_challenge" parameter is requested

Redirect network trace

My startup is (sorry long and) here:

public void ConfigureServices( IServiceCollection services )
    {
        services.AddIdentity<ApplicationUser, IdentityRole>( options =>
                {
                    options.SignIn.RequireConfirmedEmail = true;
                } )
            .AddEntityFrameworkStores<CourseRegContext>()
            .AddDefaultTokenProviders();


        var cs = Configuration.GetConnectionString( "DefaultConnection" );
        var skipHTTPS = Configuration.GetValue<bool>( "LocalTest:skipHTTPS" );
        services.Configure<MvcOptions>( options =>
        {
            if ( /*Environment.IsDevelopment() && */!skipHTTPS )
            {
                options.Filters.Add( new RequireHttpsAttribute() );
                options.EnableEndpointRouting = false;
            }
        } );

        services.AddMvc()
            .SetCompatibilityVersion( CompatibilityVersion.Version_2_1 )
            .AddNewtonsoftJson(
                options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            );

        services.AddMvc( config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            config.Filters.Add( new AuthorizeFilter( policy ) );
            config.EnableEndpointRouting = false;

        } ).AddRazorPagesOptions( options =>
        {
            options.Conventions.AllowAnonymousToFolder( "/Oops" );
            options.Conventions.AuthorizeFolder( "/Test" );
        } );

        services.AddMemoryCache();

        services.AddHttpsRedirection( options =>
        {
            options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
            if ( Environment.IsDevelopment() )
            {
                options.HttpsPort = 44311;
            }
            else
            {
                options.HttpsPort = 443;
            }
        } );

        services.AddHsts( options =>
        {
            options.Preload = true;
            options.IncludeSubDomains = true;
            options.MaxAge = TimeSpan.FromHours( 1 );
        } );

        AddAuthorisation( services );
    }

    private void AddAuthorisation( IServiceCollection services )
    {
        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        services.AddAuthentication( options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        } )
        .AddCookie( "Cookies" )
        .AddOpenIdConnect( "oidc", options =>
        {
            options.Authority = "https://localhost:41012";

            options.ClientId = "validId";
            options.ClientSecret = "somesecret";
            options.ResponseType = "code";
            options.Scope.Add( "roles" );
            options.GetClaimsFromUserInfoEndpoint = true;
            options.SaveTokens = true;
            //options.UsePkce = true;
        } );

        //services.AddAuthorization();

        services.AddAuthorization( options =>
        {
            options.AddPolicy( AuthPolicies.GlobalAdmin, policy =>
                policy.RequireRole( ApplicationRoles.Administrator ) );
            options.AddPolicy( AuthPolicies.CourseAdmin, policy =>
                policy.RequireRole(
                    ApplicationRoles.Administrator,
                    ApplicationRoles.CourseAdmin ) );
            options.AddPolicy( AuthPolicies.Presenter, policy =>
                policy.RequireRole( ApplicationRoles.CourseViewer ) );
            options.AddPolicy( AuthPolicies.UserAdmin, policy =>
                policy.RequireRole( ApplicationRoles.UserAdmin, ApplicationRoles.Administrator ) );
        } );
     }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure( IApplicationBuilder app, IHostingEnvironment env )
    {
        if ( env.IsDevelopment() )
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler( "/Oops/C500" );
            app.UseHsts( options => options.MaxAge( hours: 1 ).IncludeSubdomains() ); //todo when confident it is working, use 180 days
        }

        app.UseStatusCodePagesWithRedirects( "/Oops/C{0}" );

        app.UseXXssProtection( options => options.EnabledWithBlockMode() );
        app.UseXContentTypeOptions();

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints( endpoints =>
        {
            //endpoints.MapDefaultControllerRoute()
                //.RequireAuthorization();
        } );

        app.UseMvc();
    }

I wonder if it is something do with MVC and EndPoints as part of the upgrade to .NET Core 3.1, but I am unsure how to keep the rest of the project working and yet still get the IDS integration.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I started a blank project and got it authenticating with no other code attached and it worked. So I then put each line back fixing each DI error until I saw the error again. It was to do with services.AddIdentity<ApplicationUser, IdentityRole> which I guess makes sense as it adds login authentication stuff as well as the managers. So, this line needs to be removed, but also need to remove all references to the usermanager etc too.

One mass refactor later and have now broken the redirect to IDS, but hopefully will get it redirecting. (it's now just acting like there is no authentication at all)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...