Use oauth2 for authentication and Identity for authorization - asp.net-core

I currently have an aspnet core 2.1 application where authentication and authorization is handled with Identity, where users, roles and claims are all saved in de database.
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Is there a way to switch (only) the authentication to oauth2 and then search the user in the database (when found based on email or login) and then tell Identity that this user is logged in? That way I should not change the authorization functionality in the controllers.
I already tested following oauth2 authentication (provider is github) with success.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "GitHub";
})
.AddCookie()
.AddOAuth("GitHub", options =>
{
options.ClientId = "my client id";
options.ClientSecret = "my client secret";
options.CallbackPath = new PathString("/Home/Index");
options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
options.TokenEndpoint = "https://github.com/login/oauth/access_token";
options.UserInformationEndpoint = "https://api.github.com/user";
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user);
}
};
});
Problem is that code like if (_signInManager.IsSignedIn(User)) won't work anymore as this authentication is via oath2.

Related

How to use cookie authentication for Ocelot apigatway

I am using IdentitySever which issue id_token. Their is another website which uses cookie authentication with openidconnect. Code is as below
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Allow sign in via an OpenId Connect provider like OneLogin
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(12);
options.SlidingExpiration = false;
options.Cookie.Name = "TestApp";
})
.AddOpenIdConnect(options =>
{
options.RequireHttpsMetadata = false;
options.SignInScheme = "Cookies";
options.ClientId = "Test";
options.ClientSecret = "client_sceret";
options.Authority = "http://localhost:57744/identity";
options.ResponseType = "id_token";
options.GetClaimsFromUserInfoEndpoint = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = redirectToIdentityProvider
};
}
);
services.Configure<OidcOptions>(Configuration.GetSection("oidc"));
}
I am creating another Apigateway. If user is logged in website than should be able to make api request through gateway. Both website and gateway will be hosted under same sub-domain While making request to apigateway I will pass cookie created by website in header and want to utilize it at gateway to get claims from identityserver.
Is their way to integrate cookie authentication and identity sever with ocelot gateway?

SignalR authentication with Blazor wasm Bearer Token

I authenticated to Signalr with Bearer token and signalr said Authentication was
successful.
But Signalr Hub Context.Identity.User.Name is null after authentication.
How can i access to authenticated user information in SignalR Hub for connectionid and user mapping.
My Startup.cs code for authentication.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = "https://security.minima.local";
options.Audience = "blazor_web_app_api";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new
TokenValidationParameters()
{
ValidateAudience = false
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/notification")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
})
.AddIdentityServerJwt();
You need to tell the TokenValidator which claim is the name and role claim and you do that by setting:
.AddMyJwtBearer(opt =>
{
...
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";

Blazor serverside + Cognito Logout?

I'm kinda new to blazor and I'm having issues with logging users out of the application. I've looked at various documents and tutorials but I haven't found anything mentioning logging out. I've tried calling the Cognito logout endpoint (https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html) but my application still sees the user as authenticated. I also tried getting the access_token using the answer in this thread How do I get the access token from a blazor (server-side) web app? but it always returns null for me. The isAuthenticated property always return true regardless of what I do. Anyone got any ideas?
In startup
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ResponseType = "code";
options.SaveTokens = true;
options.RemoteSignOutPath = "/signout";
options.MetadataAddress = Configuration["Authentication:Cognito:MetadataAddress"];
options.ClientId = Configuration["Authentication:Cognito:ClientId"];
options.ClientSecret = Configuration["Authentication:Cognito:ClientSecret"];
});
In LoginDisplay.razor
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
identity = user.Identity as ClaimsIdentity;
var isAuthenticated = identity.IsAuthenticated;
email = identity!.Claims.FirstOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value ?? string.Empty;
var userData = await userService.GetUserByEmail(email.ToLower());
userData.Then(u =>
userRole = u.Role
, () =>
userRole = UserRole.Anonymous
);
}
According to Microsoft's document AuthenticationStateProvider service, we should not use AuthenticationStateProvider directly since it does not automatically notified of authentication state data changes.
Use AuthrizedView and CascadingStateProvider components instead.

How do I get more recent userinfo with AddJwtBearer

We use IdentityServer to handle SSO authentication across our apps.
My application is an Aspnet core 3.0 website that passes the users Token to javascript. The javascript then calls a separate aspnet 2.2 API.
Problem: Logging a user out and back in does not update the ClaimsPrincipal on the API with new claims.
I have confirmed that the Web application has the new claims.
If I login Incognito or clear my cookies the new claim shows up in the API.
I am not sure where the responsibility for getting the claims should be and how to fix it. I assume the claims are part of the encrypted access_token, therefore I assume the Web app is sending a stale access_token to the API. So is the Web App what I need to fix? And what would be the proper fix?
Api Startup Code
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Bearer";
options.DefaultChallengeScheme = "Bearer";
})
.AddJwtBearer(options =>
{
options.Authority = oidcSettings.Authority;
options.Audience = oidcSettings.ApplicationName;
options.RequireHttpsMetadata = true;
});
Web App Startup Code
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext => { cookieContext.CookieOptions.SameSite = SameSiteMode.None; };
options.OnDeleteCookie = cookieContext =>
{
cookieContext.CookieOptions.SameSite = SameSiteMode.None; // this doesn't appear to get called.
};
});
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
}).AddCookie("Cookies", options =>
{
options.SlidingExpiration = false;
options.ExpireTimeSpan = TimeSpan.FromHours(8);
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = oidcSettings.Authority;
options.RequireHttpsMetadata = true;
options.ClientId = oidcSettings.ClientId;
options.ClientSecret = oidcSettings.ClientKey;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("offline_access");
options.Scope.Add(oidcSettings.ApplicationName);
options.ClaimActions.MapJsonKey("role", "role"); // claims I am looking for are mapped here
options.Events.OnUserInformationReceived = async (context) =>
{
await Task.CompletedTask; // confirmed that after new sign in I can see updated info here.
};
});
TLDR: Javascript from Web app calls Api using access_token. When user logs out and logs back in, the API does not receive updated claims. I am not sure if the issue is the API needs to call out to identity server for user info or the Web App is not signing out properly and needs to send a fresh access_token?

403 - Forbidden: Access is denied. after Login ASP.Net Core 2.2

I Recently Changed My Hosting Server,
I Randomly Get This Error Message after Login:
403 - Forbidden: Access is denied.
You do not have permission to view this directory or page using the credentials that you supplied.
and when I Delete The related cookies in Browser The Site Loads Again.
I Use cookie authentication without ASP.NET Core Identity described here:
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-2.2
startup.cs Code:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.LoginPath = "/Login";
options.LogoutPath = "/Logout";
options.ExpireTimeSpan = TimeSpan.FromMinutes(43200);
});
and login Part Code:
User user = await _userService.LoginUserAsync(login.Email, login.Password);
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Name,user.UserName),
new Claim(ClaimTypes.NameIdentifier,user.UserID.ToString())
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var pricipal = new ClaimsPrincipal(identity);
var properties = new AuthenticationProperties()
{
IsPersistent = login.RememberMe
};
await HttpContext.SignInAsync(pricipal, properties);
I never had same problem on my previous Hosting Plan.
Is This Problem Related to Host Settings?