Login Logik aktualisiert
This commit is contained in:
@@ -1,80 +1,39 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Watcher.ViewModels;
|
|
||||||
|
|
||||||
namespace Watcher.Controllers;
|
namespace Watcher.Controllers;
|
||||||
|
|
||||||
public class AuthController : Controller
|
public class AuthController : Controller
|
||||||
{
|
{
|
||||||
private readonly IConfiguration _config;
|
public IActionResult Login()
|
||||||
|
|
||||||
public AuthController(IConfiguration config)
|
|
||||||
{
|
{
|
||||||
_config = config;
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
public IActionResult SignIn()
|
||||||
public IActionResult Login(string? returnUrl = null)
|
|
||||||
{
|
{
|
||||||
var vm = new LoginViewModel { ReturnUrl = returnUrl };
|
|
||||||
return View(vm);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[ValidateAntiForgeryToken]
|
|
||||||
public async Task<IActionResult> Login(LoginViewModel model)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return View(model);
|
|
||||||
|
|
||||||
// Beispielhafte, harte lokale Benutzerprüfung
|
|
||||||
if (model.Username == "admin" && model.Password == "password")
|
|
||||||
{
|
|
||||||
var claims = new List<Claim>
|
|
||||||
{
|
|
||||||
new Claim(ClaimTypes.Name, model.Username),
|
|
||||||
new Claim(ClaimTypes.Role, "Admin")
|
|
||||||
};
|
|
||||||
|
|
||||||
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
||||||
var principal = new ClaimsPrincipal(identity);
|
|
||||||
|
|
||||||
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
|
|
||||||
|
|
||||||
return Redirect(model.ReturnUrl ?? "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelState.AddModelError("", "Ungültiger Benutzername oder Passwort");
|
|
||||||
return View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[ValidateAntiForgeryToken]
|
|
||||||
public IActionResult SignIn(string? returnUrl = null)
|
|
||||||
{
|
|
||||||
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Auth", new { returnUrl });
|
|
||||||
return Challenge(new AuthenticationProperties
|
return Challenge(new AuthenticationProperties
|
||||||
{
|
{
|
||||||
RedirectUri = redirectUrl
|
RedirectUri = "/"
|
||||||
}, "oidc");
|
}, "oidc");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult ExternalLoginCallback(string? returnUrl = null)
|
|
||||||
{
|
|
||||||
return Redirect(returnUrl ?? "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public async Task<IActionResult> Logout()
|
public async Task<IActionResult> Logout()
|
||||||
|
{
|
||||||
|
// Lokales Cookie löschen
|
||||||
|
await HttpContext.SignOutAsync("Cookies");
|
||||||
|
|
||||||
|
// Externes OIDC-Logout initiieren
|
||||||
|
await HttpContext.SignOutAsync("oidc", new AuthenticationProperties
|
||||||
{
|
{
|
||||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
RedirectUri = "/" // Nach Logout zurück zur Startseite oder Login-Seite
|
||||||
|
});
|
||||||
|
|
||||||
return RedirectToAction("Index", "Home");
|
return RedirectToAction("Index", "Home");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public IActionResult Info()
|
public IActionResult Info()
|
||||||
|
@@ -55,17 +55,27 @@ builder.Services.AddDbContext<AppDbContext>((serviceProvider, options) =>
|
|||||||
builder.Services.AddAuthentication(options =>
|
builder.Services.AddAuthentication(options =>
|
||||||
{
|
{
|
||||||
options.DefaultScheme = "Cookies";
|
options.DefaultScheme = "Cookies";
|
||||||
options.DefaultChallengeScheme = "oidc";
|
options.DefaultChallengeScheme = "Cookies"; // Nur wenn kein OIDC erzwungen wird
|
||||||
})
|
})
|
||||||
.AddCookie("Cookies")
|
.AddCookie("Cookies", options =>
|
||||||
.AddOpenIdConnect("oidc", options =>
|
|
||||||
{
|
{
|
||||||
var config = builder.Configuration.GetSection("Authentication:PocketID");
|
options.LoginPath = "/Account/Login"; // Falls eigene Login-Seite
|
||||||
options.Authority = config["Authority"];
|
});
|
||||||
options.ClientId = config["ClientId"];
|
|
||||||
options.ClientSecret = config["ClientSecret"];
|
// PocketID nur konfigurieren, wenn aktiviert
|
||||||
|
var pocketIdSection = builder.Configuration.GetSection("Authentication:PocketID");
|
||||||
|
var pocketIdEnabled = pocketIdSection.GetValue<bool>("Enabled");
|
||||||
|
|
||||||
|
if (pocketIdEnabled)
|
||||||
|
{
|
||||||
|
builder.Services.AddAuthentication()
|
||||||
|
.AddOpenIdConnect("oidc", options =>
|
||||||
|
{
|
||||||
|
options.Authority = pocketIdSection["Authority"];
|
||||||
|
options.ClientId = pocketIdSection["ClientId"];
|
||||||
|
options.ClientSecret = pocketIdSection["ClientSecret"];
|
||||||
options.ResponseType = "code";
|
options.ResponseType = "code";
|
||||||
options.CallbackPath = config["CallbackPath"];
|
options.CallbackPath = pocketIdSection["CallbackPath"];
|
||||||
options.SaveTokens = true;
|
options.SaveTokens = true;
|
||||||
|
|
||||||
options.GetClaimsFromUserInfoEndpoint = true;
|
options.GetClaimsFromUserInfoEndpoint = true;
|
||||||
@@ -76,7 +86,7 @@ builder.Services.AddAuthentication(options =>
|
|||||||
options.Scope.Add("email");
|
options.Scope.Add("email");
|
||||||
|
|
||||||
options.Events = new OpenIdConnectEvents
|
options.Events = new OpenIdConnectEvents
|
||||||
{
|
{
|
||||||
OnTokenValidated = async ctx =>
|
OnTokenValidated = async ctx =>
|
||||||
{
|
{
|
||||||
var db = ctx.HttpContext.RequestServices.GetRequiredService<AppDbContext>();
|
var db = ctx.HttpContext.RequestServices.GetRequiredService<AppDbContext>();
|
||||||
@@ -112,9 +122,10 @@ builder.Services.AddAuthentication(options =>
|
|||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
@@ -145,7 +156,7 @@ app.UseStaticFiles();
|
|||||||
|
|
||||||
app.MapControllerRoute(
|
app.MapControllerRoute(
|
||||||
name: "default",
|
name: "default",
|
||||||
pattern: "{controller=Home}/{action=Index}/{id?}"
|
pattern: "{controller=Auth}/{action=Login}/"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,36 +1,28 @@
|
|||||||
@model Watcher.ViewModels.LoginViewModel
|
@model Watcher.ViewModels.LoginViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Login";
|
ViewData["Title"] = "Login";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h2>Anmelden</h2>
|
<div class="login-container">
|
||||||
|
<h2>Login</h2>
|
||||||
|
|
||||||
<form asp-action="Login" method="post">
|
<form asp-action="Login" method="post">
|
||||||
<div class="form-group">
|
<div>
|
||||||
<label asp-for="Username"></label>
|
<label asp-for="Username"></label>
|
||||||
<input asp-for="Username" class="form-control" />
|
<input asp-for="Username" />
|
||||||
<span asp-validation-for="Username" class="text-danger"></span>
|
<span asp-validation-for="Username"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="Password"></label>
|
<label asp-for="Password"></label>
|
||||||
<input asp-for="Password" class="form-control" type="password" />
|
<input asp-for="Password" type="password" />
|
||||||
<span asp-validation-for="Password" class="text-danger"></span>
|
<span asp-validation-for="Password"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<input type="hidden" asp-for="ReturnUrl" />
|
<hr />
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Anmelden</button>
|
<form asp-controller="Auth" asp-action="SignIn" method="get">
|
||||||
</form>
|
<button type="submit">Mit PocketID anmelden</button>
|
||||||
|
</form>
|
||||||
<hr />
|
</div>
|
||||||
|
|
||||||
<form asp-action="LoginWithOidc" method="post">
|
|
||||||
<input type="hidden" name="returnUrl" value="@Model.ReturnUrl" />
|
|
||||||
<button type="submit" class="btn btn-outline-secondary">Mit PocketID anmelden</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
@section Scripts {
|
|
||||||
<partial name="_ValidationScriptsPartial" />
|
|
||||||
}
|
|
||||||
|
@@ -62,10 +62,10 @@
|
|||||||
<h4>Watcher</h4>
|
<h4>Watcher</h4>
|
||||||
<ul class="nav flex-column">
|
<ul class="nav flex-column">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/">Dashboard</a>
|
<a class="nav-link" href="/Home/Index">Dashboard</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item"></li>
|
<li class="nav-item"></li>
|
||||||
<a class="nav-link" href="/Uptime">Uptime</a>
|
<a class="nav-link" href="/Uptime/Overview">Uptime</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/Server/Overview">Servers</a>
|
<a class="nav-link" href="/Server/Overview">Servers</a>
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
"Authentication": {
|
"Authentication": {
|
||||||
"UseLocal": true,
|
"UseLocal": true,
|
||||||
|
"PocketIDEnabled": true,
|
||||||
"PocketID": {
|
"PocketID": {
|
||||||
"Authority": "https://pocketid.triggermeelmo.com",
|
"Authority": "https://pocketid.triggermeelmo.com",
|
||||||
"ClientId": "629a5f42-ab02-4905-8311-cc7b64165cc0",
|
"ClientId": "629a5f42-ab02-4905-8311-cc7b64165cc0",
|
||||||
|
Reference in New Issue
Block a user