Custom Implementation Example
Tämä opas käy läpi rakentamisen täydellisen mukautetun turvallisuusratkaisun käyttäen istuntoon perustuvaa todennusta. Opit, miten neljä ydintoimintoliittymää toimii yhdessä toteuttamalla ne alusta alkaen.
Spring Security -integraatio konfiguroi automaattisesti kaiken, mitä täällä on esitetty. Rakenna vain mukautettu turvallisuus, jos sinulla on erityisiä vaatimuksia tai et käytä Spring Bootia.
Mitä rakennat
Toimiva turvallisuusjärjestelmä, jossa on neljä luokkaa:
- SecurityConfiguration - Määrittelee turvallisuuskäyttäytymisen ja uudelleenohjauspaikat
- SecurityContext - Seuraa, kuka on kirjautuneena sisään käyttäen HTTP-istuntoja
- SecurityManager - Koordinoi turvallisuustarkistuksia ja tarjoaa kirjautumis-/uloskirjautumismahdollisuuden
- SecurityRegistrar - Yhdistää kaiken sovelluksen käynnistämisen yhteydessä
Esimerkki käyttää istuntoon perustuvaa tallennusta, mutta voit toteuttaa samat toimintoliittymät käyttäen tietokantakyselyitä, LDAP:ta tai mitä tahansa muuta todennusbackendiä.
Miten osat toimivat yhdessä
Prosessi:
SecurityRegistrarsuorittaa käynnistyksen yhteydessä, luo hallitsijan, rekisteröi arvioijat ja liittää tarkkailijanSecurityManagerkoordinoi kaiken - se tarjoaa kontekstin ja konfiguraation arvioijilleSecurityContextvastaa kysymykseen "Kuka on kirjautuneena?" lukemalla HTTP-istunnoistaSecurityConfigurationvastaa kysymykseen "Mihin ohjata?" kirjautumis- ja pääsykielto -sivuilleEvaluatorstekevät pääsypäätöksiä käyttäen kontekstia ja konfiguraatiota
Vaihe 1: Määritä turvallisuuskonfiguraatio
Konfigurointi kertoo turvallisuusjärjestelmälle, miten käyttäytyä ja minne ohjata käyttäjiä:
package com.securityplain.security;
import com.webforj.router.history.Location;
import com.webforj.router.security.RouteSecurityConfiguration;
import java.util.Optional;
/**
* Turvallisuuskonfiguraatio sovellukselle.
*
* <p>
* Määrittelee minne ohjata käyttäjiä, kun todennus on vaadittu tai pääsy on kielletty.
* </p>
*/
public class SecurityConfiguration implements RouteSecurityConfiguration {
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isSecureByDefault() {
return false;
}
@Override
public Optional<Location> getAuthenticationLocation() {
return Optional.of(new Location("/login"));
}
@Override
public Optional<Location> getDenyLocation() {
return Optional.of(new Location("/access-denied"));
}
}
isEnabled() = true- Turvallisuus on aktiivinenisSecureByDefault() = false- Reitit ovat julkisia, ellei toisin ole merkattu (käytätruevaatiaksesi todennusta kaikilla reiteillä oletuksena)/login- Minne todennusta vailla olevat käyttäjät menevät/access-denied- Minne todennetut käyttäjät, joilla ei ole oikeuksia, menevät
Vaihe 2: Toteuta turvallisuuskonteksti
Konteksti seuraa, kuka on kirjautuneena. Tämä toteutus käyttää HTTP-istuntoja käyttäjätietojen tallentamiseen:
Miten se toimii:
isAuthenticated()tarkistaa, onko istunnossa käyttäjäpäägetPrincipal()noutaa käyttäjätunnuksen istuntotallennuksestahasRole()tarkistaa, sisältääkö käyttäjän roolijoukko määritellyn roolingetAttribute()/setAttribute()hallitsevat mukautettuja turvallisuusattribuuttejaEnvironment.getSessionAccessor()tarjoaa säikeestä turvallisen pääsyn istuntoon
Vaihe 3: Luo turvallisuusmanageri
Hallitsija koordinoi turvallisuuspäätöksiä. Se laajentaa AbstractRouteSecurityManager-luokkaa, joka käsittelee arvioijaketjuja ja pääsyn eväämistä:
Miten se toimii:
- Laajentaa
AbstractRouteSecurityManagerperii arvioijaketjun logiikan - Tarjoaa
getConfiguration()jagetSecurityContext()-toteutukset - Lisää
login()käyttäjien todennusta varten ja tallentaa kirjautumistiedot istuntoon - Lisää
logout()tyhjentää istunnon ja ohjaa kirjautumissivulle - Käyttää
SessionObjectTableyksinkertaista istuntotallennusta varten - Tallentaa itsensä
ObjectTablesovelluksen laajuista käyttöä varten
Vaihe 4: Liitä kaikki käynnistyksessä
Rekisteröijä yhdistää kaikki osat, kun sovellus käynnistyy:
package com.securityplain.security;
import com.webforj.App;
import com.webforj.AppLifecycleListener;
import com.webforj.annotation.AppListenerPriority;
import com.webforj.router.Router;
import com.webforj.router.security.RouteSecurityObserver;
import com.webforj.router.security.evaluator.AnonymousAccessEvaluator;
import com.webforj.router.security.evaluator.DenyAllEvaluator;
import com.webforj.router.security.evaluator.PermitAllEvaluator;
import com.webforj.router.security.evaluator.RolesAllowedEvaluator;
/**
* Rekisteröi reitin turvallisuuskomponentit sovelluksen käynnistämisen aikana.
*
* <p>
* Määritys turvallisuusmanagerista ja arvioijista reitittimen kanssa.
* </p>
*/
@AppListenerPriority(1)
public class SecurityRegistrar implements AppLifecycleListener {
/**
* {@inheritDoc}
*/
@Override
public void onWillRun(App app) {
// Luo turvallisuusmanageri
SecurityManager securityManager = new SecurityManager();
securityManager.saveCurrent(securityManager);
// Rekisteröi sisäänrakennetut arvioijat prioriteetit
securityManager.registerEvaluator(new DenyAllEvaluator(), 0);
securityManager.registerEvaluator(new AnonymousAccessEvaluator(), 1);
securityManager.registerEvaluator(new PermitAllEvaluator(), 2);
securityManager.registerEvaluator(new RolesAllowedEvaluator(), 3);
// Luo turvallisuustarkkailija ja liitä reitittimeen
RouteSecurityObserver securityObserver = new RouteSecurityObserver(securityManager);
Router router = Router.getCurrent();
if (router != null) {
router.getRenderer().addObserver(securityObserver);
}
}
}
Rekisteröi kuuntelija:
Luo src/main/resources/META-INF/services/com.webforj.AppLifecycleListener seuraavalla sisällöllä:
com.securityplain.security.SecurityRegistrar
Tämä rekisteröi AppLifecycleListener, jotta se ajetaan sovelluksen käynnistyessä.
Miten se toimii:
- Suoritetaan aikaisessa vaiheessa (
@AppListenerPriority(1)) määrittääkseen turvallisuus ennen reittien lataamista - Luo turvallisuusmanagerin ja tallentaa sen globaalisti
- Rekisteröi sisäänrakennetut arvioijat prioriteettijärjestyksessä (alemmat numerot suoritetaan ensin)
- Luo tarkkailijan, joka keskeyttää navigoinnin
- Liittää tarkkailijan reitittimeen, jotta turvallisuustarkastukset tapahtuvat automaattisesti
Kun tämä on suoritettu, turvallisuus on aktiivinen kaikessa navigoinnissa.
Käytä toteutustasi
Luo kirjautumisnäkymä
Seuraava näkymä käyttää Login komponenttia.
package com.securityplain.views;
import com.securityplain.security.SecurityManager;
import com.webforj.component.Composite;
import com.webforj.component.login.Login;
import com.webforj.router.Router;
import com.webforj.router.annotation.FrameTitle;
import com.webforj.router.annotation.Route;
import com.webforj.router.history.Location;
import com.webforj.router.security.annotation.AnonymousAccess;
@Route("/login")
@FrameTitle("Kirjaudu sisään")
@AnonymousAccess
public class LoginView extends Composite<Login> {
private Login self = getBoundComponent();
public LoginView() {
self.onSubmit(e -> {
var result = SecurityManager.getCurrent().login(
e.getUsername(), e.getPassword()
);
if (result.isGranted()) {
Router.getCurrent().navigate(new Location("/"));
} else {
self.setError(true);
self.setEnabled(true);
}
});
self.whenAttached().thenAccept(c -> self.open());
}
}