很多人我都在努力设置身份服务器 . 这是我的情况,因为我还没有找到合适的解决方案
-
我有一个包含MVC客户端的解决方案(.net核心2.1)
-
我有一个单独的解决方案,其中包含与IdentityServer相关的代码
一切似乎都可以正常工作以验证用户凭据,但是当我想在登录成功后重定向时,会导致找不到404页面 . 下面的代码提供更多信息
LoginController from the IdentityServer solution
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login([FromBody]LoginDto login)
{
if (!ModelState.IsValid)
return BadRequest("Missing email or password");
try
{
var loginModel = Map(login);
var user = await _loginService.LoginAsync(loginModel);
await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName));
return Ok();
}
catch (UserNotFoundException)
{
return BadRequest("User not found");
}
catch (LoginFailedException)
{
return Unauthorized();
}
catch (AccountLockedOutException)
{
return StatusCode((int) HttpStatusCode.Forbidden);
}
}
private static LoginModel Map(LoginDto login)
{
return new LoginModel
{
Email = login.Email,
Password = login.Password,
RememberMe = login.RememberMe
};
}
The configuration from the Startup class of Identity solution
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<IdentityServerDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("IdentityServer"));
});
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityServerDbContext>()
.AddDefaultTokenProviders();
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "Miricle.IdentityServer.Api";
});
services.AddMvc();
services.AddScoped<ILoginService, LoginService>();
services.AddScoped<IApplicationSignInManager, ApplicationSignInManager>();
services.AddScoped<IApplicationUserManager, ApplicationUserManager>();
services.AddCors(options =>
{
options.AddPolicy(CorsPolicyName, policy =>
{
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.AllowAnyOrigin();
policy.AllowCredentials();
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseIdentityServer();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.UseCors(CorsPolicyName);
}
}
The LoginController from the .NET Core MVC Client
public class LoginController : Controller
{
private readonly HttpClient _httpClient;
public LoginController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Index()
{
var model = new LoginViewModel();
return View(model);
}
[HttpPost]
[Route("/Login")]
[AllowAnonymous]
public async Task<IActionResult> Login([FromForm] LoginViewModel login)
{
if (!ModelState.IsValid) return View("Index", login);
_httpClient.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, "https://localhost:44374/api/login");
var content = JsonConvert.SerializeObject(new LoginViewModel()
{
Email = login.Email,
Password = login.Password,
RememberMe = login.RememberMe,
});
request.Content = new StringContent(content, Encoding.UTF8, "application/json");
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return Redirect("/Home/Index");
}
}
The configuration from the Startup of the MVC Client
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "Miricle.Crm.Web";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("Miricle.IdentityServer.Api");
options.Scope.Add("offline_access");
});
services.AddMvcCore(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddRazorViewEngine()
.AddAuthorization()
.AddJsonFormatters();
services.AddSingleton<HttpClient>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddCors(options =>
{
options.AddPolicy(CorsPolicyName, policy =>
{
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.AllowAnyOrigin();
policy.AllowCredentials();
});
});
}
// 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.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseAuthentication();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "",
defaults: new { controller = "Login", action = "Index" });
});
app.UseCors(CorsPolicyName);
}
}
我一直试图将这项工作推迟近一个星期,我确信它是愚蠢的,但我找不到它:/
1 回答
我不明白你的代码试图做什么,但是从你预期的目标的描述,我希望看到
MVC客户端,其控制器或控制器方法受[Authorize]属性保护
包含登录屏幕的Controller和View的身份服务器,在身份验证后重定向回客户端
有一个例子,涵盖了你正在尝试做的事情
https://identityserver4.readthedocs.io/en/release/quickstarts/3_interactive_login.html
但如果您不想通过该示例,那么您可以直接转到工作代码:
https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/3_ImplicitFlowAuthentication