Custom Implementation Example
Tämä opas käy läpi täydellisen mukautetun turvallisuustoteutuksen luomisen, joka käyttää istuntopohjaista todennusta. Opit, miten neljä keskeistä rajapintaa toimivat yhdessä toteuttamalla ne alusta alkaen.
Spring Security -integraatio määrittää automaattisesti kaiken, mitä tässä on esitetty. Rakenna mukautettu turvallisuus vain, 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 HTTP-istuntojen avulla
- SecurityManager - Koordinoi turvallisuustarkastuksia ja tarjoaa kirjautumis-/uloskirjautumismahdollisuudet
- SecurityRegistrar - Yhdistää kaiken sovelluksen käynnistyksessä
Tässä esimerkissä käytetään istuntopohjaista tallennusta, mutta voit toteuttaa samat rajapinnat käyttämällä tietokantakyselyitä, LDAP:ia tai mitä tahansa muuta todennuspohjaa.
Miten osat toimivat yhdessä
Virtaus:
SecurityRegistrartoimii käynnistyksen aikana, luo hallitsijan, rekisteröi arvioijat ja liittää tarkkailijanSecurityManagerkoordinoi kaiken - se antaa kontekstin ja määrityksen arvioijilleSecurityContextvastaa kysymykseen "Kuka on kirjautuneena?" lukemalla HTTP-istunnoistaSecurityConfigurationvastaa kysymykseen "Minne ohjata?" kirjautuminen ja pääsy hylätty -sivuilleEvaluatorstekevät pääsypäätöksiä käyttämällä kontekstia ja määritystä
Vaihe 1: Määritä turvallisuusmääritys
Määritys kertoo turvallisuusjärjestelmälle, miten sen tulisi toimia ja minne käyttäjät tulisi ohjata:
package com.securityplain.security;
import com.webforj.router.history.Location;
import com.webforj.router.security.RouteSecurityConfiguration;
import java.util.Optional;
/**
* Turvallisuusmääritys sovellukselle.
*
* <p>
* Määrittelee, minne käyttäjät ohjataan, kun todennus on vaadittu tai pääsy on hylätty.
* </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 niitä ole merkitty (käytätrue, jos haluat vaatia todennusta kaikilla reiteillä oletuksena)/login- Minne toteamattomat käyttäjät menevät/access-denied- Minne tunnistetut 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 käyttäjän pääsytieto olemassa istunnossagetPrincipal()palauttaa käyttäjänimen istuntoTallennuksestahasRole()tarkistaa, sisältääkö käyttäjän roolijoukko määritetyn roolingetAttribute()/setAttribute()hallinnoi mukautettuja turvallisuusominaisuuksiaEnvironment.getSessionAccessor()tarjoaa säikeen turvallisen pääsyn istuntoon
Vaihe 3: Luo turvallisuuden hallinta
Hallinta koordinoi turvallisuuspäätöksiä. Se laajentaa AbstractRouteSecurityManager-luokkaa, joka käsittelee arvioijaketjuja ja pääsyn hylkäämistä:
Miten se toimii:
- Laajentaa
AbstractRouteSecurityManagersaadakseen arvioijaketjun logiikan - Tarjoaa
getConfiguration()jagetSecurityContext()toteutukset - Lisää
login()autentikoimaan käyttäjiä ja tallentamaan todennustiedot istuntoon - Lisää
logout()tyhjentämään istunnon ja ohjaamaan kirjautumissivulle - Käyttää
SessionObjectTableyksinkertaiseen istuntotallennukseen - Tallentaa itsensä
ObjectTablesovelluksen laajuiseen käyttöön
Vaihe 4: Yhdistä kaikki käynnistyksessä
Rekisteröijä yhdistää kaikki osat sovelluksen käynnistyessä:
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äynnistyksen aikana.
*
* <p>
* Määrittelee turvallisuuden hallinnan ja arvioijat reitittimen kanssa.
* </p>
*/
@AppListenerPriority(1)
public class SecurityRegistrar implements AppLifecycleListener {
/**
* {@inheritDoc}
*/
@Override
public void onWillRun(App app) {
// Luo turvallisuuden hallinta
SecurityManager securityManager = new SecurityManager();
securityManager.saveCurrent(securityManager);
// Rekisteröi sisäänrakennetut arvioijat prioriteetti järjestyksessä
securityManager.registerEvaluator(new DenyAllEvaluator(), 0);
securityManager.registerEvaluator(new AnonymousAccessEvaluator(), 1);
securityManager.registerEvaluator(new PermitAllEvaluator(), 2);
securityManager.registerEvaluator(new RolesAllowedEvaluator(), 3);
// Luo turvallisuustarkkailija ja liitä se 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 sinun AppLifecycleListener, jotta se toimii sovelluksen käynnistyksessä.
Miten se toimii:
- Toimii varhain (
@AppListenerPriority(1)) määrittämään turvallisuuden ennen reittien lataamista - Luo turvallisuuden hallinnan ja tallentaa sen globaalisti
- Rekisteröi sisäänrakennetut arvioijat prioriteetti järjestyksessä (alhaisemmat numerot suoritetaan ensin)
- Luo tarkkailijan, joka keskeyttää navigoinnin
- Liittää tarkkailijan reitittimeen siten, että turvallisuustarkastukset tapahtuvat automaattisesti
Kun tämä on suoritettu, turvallisuus on aktivoitu kaikelle navigoinnille.
Toteuttamisesi käyttäminen
Luo kirjautumissivu
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("Kirjautuminen")
@AnonymousAccess
public class LoginView extends Composite<Login> {
private final 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());
}
}