0

We have a .net core application using traditional login with JWT bearer token mechanism, Now I have to give another option to use Azure SSO through SAML2. So login page will include another option called sign with SSO. My doubt is how can we use both in one application without conflicting with the other.

Existing code is below

 services.Configure<CookieTempDataProviderOptions>(options =>
            {
                options.Cookie.SameSite = SameSiteMode.Lax; // By default this is set to 'Strict'.
            });
            services
                .AddMvc(options => options.EnableEndpointRouting = false)
                .AddRazorPagesOptions(options =>
                {
                    options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "");
                })
                .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

            services.AddRazorPages()
                .AddRazorRuntimeCompilation();

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                try
                {
                    options.IdleTimeout = TimeSpan.FromMinutes(Configuration.GetValue<int>("SessionIdleTimeoutMinutes"));
                }
                catch (Exception)
                {
                    options.IdleTimeout = TimeSpan.FromMinutes(15);
                }
                
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

            services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath = "/Identity/Account/Login";
                options.AccessDeniedPath = new PathString("/404.html");
                options.SlidingExpiration = true;
            });

            //services.AddHttpsRedirection(options =>
            //{
            //    options.HttpsPort = 443;
            //});

            services.AddDependentServices();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "App v1",
                    Version = "v1"
                });
                var securityScheme = new OpenApiSecurityScheme
                {
                    Name = "JWT Authentication",
                    Description = "Enter JWT Bearer token **_only_**",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer", // 
                    BearerFormat = "JWT",
                    Reference = new OpenApiReference
                    {
                        Id = JwtBearerDefaults.AuthenticationScheme,
                        Type = ReferenceType.SecurityScheme
                    }
                };
                c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {securityScheme, new string[] { }}
                });
            });
            
             //services.AddSwaggerGenNewtonsoftSupport(); 
            services.AddControllers().AddJsonOptions(options =>
            options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));


            var jwtTokenSetting = Configuration.GetSection("JwtTokenSetting").Get<JwtTokenConfig>();
            services.AddSingleton(jwtTokenSetting);
            services.AddSingleton(setting);
            services.AddAuthentication()
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = true;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = jwtTokenSetting.Issuer,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtTokenSetting.Secret)),
                    ValidAudience = jwtTokenSetting.Audience,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(1),
                    RequireSignedTokens = true
                };
            });
nani
  • 15
  • 2
  • 6
  • Azure AD supports OIDC and JWT too, y'know - do you have a compelling reason to _want_ to use SAML? – Dai Oct 30 '22 at 02:39
  • _"My doubt is how can we use both in one application without conflicting with the other."_ - that's fully supported: just be sure to give them distinct ASP.NET Authentication Scheme names (tip: use named `const` strings to avoid having magic-string literals everywhere). – Dai Oct 30 '22 at 02:40

1 Answers1

0

I haven't done SAML2 myself, but I know that it is possible that the ASP.Net Core app supports multiple authentication schemas.

The general idea is:

  1. register multiple auth schemas with different authentication endpoints in your app.
  2. once the authenticated user makes requests with the auth bearer token, your auth handlers will validate the token against the schemas.

Take a look at this one.

Charles Han
  • 1,920
  • 2
  • 10
  • 19