I have 2 different C# Visual Studio 2019 16.9.4 solutions for ASP.NET Core MVC 5.0, one acting as identity provider and the other one as a client. So far, when I authenticate the client, the claims are persisted to the cookie but when token endpoint is called by oauth middleware in client application, claims get lost in HttpContext.User object. When I commented out code under Authorize/Token action, it throws an exception that JSON token cannot be extracted but upon refreshing the client app page, I'm able to retrieve claims in client app. Can you help where I'm missing for this oauth and asp.net identity. I don't want to persist claims in access-token because it can grow big
The code for identity provider
public class AuthorizeController : Controller { private readonly IConfiguration _configuration;
public AuthorizeController(IConfiguration configuration) { _configuration = configuration; } [HttpGet] public IActionResult Login(string response_type, string client_id, string redirect_uri, string scope, string state) { return View(new LoginDTO { ClientId = client_id, RedirectUri = redirect_uri, ResponseType = response_type, Scope = scope ?? string.Empty, State = state }); } [HttpPost("Login")] public async Task<IActionResult> Login(LoginDTO login) { var claims = new List<Claim> { new Claim("username", login.Username), new Claim("usertype", "administrator"), new Claim(ClaimTypes.Email, "someuser@somedev.com"), new Claim(ClaimTypes.NameIdentifier, login.Username) }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); await HttpContext.SignInAsync(claimsPrincipal, new AuthenticationProperties { IsPersistent = true }); var code = "random code here"; //build query string var queryBuilder = new QueryBuilder(); queryBuilder.Add("code", code); queryBuilder.Add("state", login.State); return Redirect($"{ login.RedirectUri }{ queryBuilder.ToString() }"); } public IActionResult Token(string grant_type, string code, string redirect_uri, string client_id) { var user = HttpContext.User; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["ClientKey"])); var securityToken = new JwtSecurityToken(issuer: _configuration["IdentityIssuer"], audience: _configuration["IdentityAudience"], expires: DateTime.UtcNow.AddDays(1), signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256) ); var accessToken = new JwtSecurityTokenHandler().WriteToken(securityToken); return Ok(new { access_token = accessToken, token_type = "Bearer" }); //var response = new //{ // access_token = accessToken, // token_type = "Bearer" //}; //Response.StatusCode = (int)HttpStatusCode.OK; //var responseJson = JsonConvert.SerializeObject(response); //var bytes = Encoding.UTF8.GetBytes(responseJson); //await Response.Body.WriteAsync(bytes, 0, bytes.Length); //return new EmptyResult(); }
The following code is in client app
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; }
public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyFolder"])) .SetApplicationName("SharedCookieApp"); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = "oauth"; }) .AddCookie("Cookies", options => { options.Cookie.HttpOnly = true; options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.IsEssential = true; }) .AddOAuth("oauth", config => { config.SignInScheme = "Cookies"; config.SaveTokens = true; config.ClientId = Configuration["ClientId"]; config.ClientSecret = Configuration["ClientKey"]; config.AccessDeniedPath = new PathString("/Home/AccessDenied"); config.CallbackPath = new PathString("/oauth/callback"); config.AuthorizationEndpoint = $"{Configuration["IdentityIssuer]}/authorize/login"; config.TokenEndpoint = $"{Configuration["IdentityIssuer"]}/authorize/token"; config.CorrelationCookie.HttpOnly = true; config.CorrelationCookie.IsEssential = true; config.CorrelationCookie.SameSite = SameSiteMode.None; config.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always; config.CorrelationCookie.Name = "Oauth.Correlation.Cookie"; }); services.AddAuthorization(options => { var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); options.AddPolicy("AuthenticatedUser", policy); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
https://stackoverflow.com/questions/67395476/claims-getting-lost-after-authenticating-using-oauth2-with-asp-net-identity-usin May 05, 2021 at 01:07PM
没有评论:
发表评论