Osa 5

Näkymä- ja metoditason auktorisointi

Tutustuimme juuri käyttäjän tunnistamiseen eli autentikointiin. Autentikoinnin lisäksi sovelluksissa on tärkeää varmistaa, että käyttäjä saa tehdä asioita, joita hän yrittää tehdä: auktorisointi. Jos käyttäjän tunnistaminen toimii mutta sovellus ei tarkista oikeuksia tarkemmin, on mahdollista päätyä esimerkiksi tilanteeseen, missä käyttäjä pääsee tekemään epätoivottuja asioita.

Näkymätason auktorisointi

Määrittelimme aiemmin oikeuksia sovelluksen polkuihin liittyen. Tämä ei kuitenkaan aina riitä, vaan käyttöliittymissä halutaan usein rajoittaa toiminta esimerkiksi käyttäjäroolien perusteella. Thymeleaf-projektiin löytyy liitännäinen, jonka avulla voimme lisätä tarkistuksia HTML-sivuille. Liitännäisen saa käyttöön lisäämällä seuraavan riippuvuuden pom.xml-tiedostoon.

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>

Kun näkymien html-elementtiin lisätään sec:-nimiavaruuden määrittely, voidaan sivulle määritellä elementtejä, joiden sisältö näytetään vain esimerkiksi tietyllä roolilla kirjautuneelle käyttäjälle. Seuraavassa esimerkissä teksti "salaisuus" näkyy vain käyttäjälle, jolla on rooli "ADMIN".

<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:th="http://www.thymeleaf.org"
        xmlns:sec="http://www.springframework.org/security/tags">

    ...
    <div sec:authorize="hasAuthority('ADMIN')">
        <p>salaisuus</p>
    </div>
    ...

Attribuutilla sec:authorize määritellään säännöt, joita tarkistuksessa käytetään. Attribuutille käy mm. arvot isAuthenticated(), hasAuthority('...') ja hasAnyAuthority('...'). Lisää sääntöjä löytyy Spring Securityn dokumentaation kohdasta Expression-Based Access Control.

Metoditason auktorisointi

Pelkän näkymätason auktorisoinnin ongelmana on se, että usein toimintaa halutaan rajoittaa tarkemmin — esimerkiksi siten, että tietyt operaatiot (esim. poisto tai lisäys) mahdollistetaan vain tietyille käyttäjille tai käyttäjien oikeuksille. Käyttöliittymän näkymää rajoittamalla ei voida rajoittaa käyttäjän tekemiä pyyntöjä, sillä pyynnöt voidaan tehdä myös "käyttöliittymän ohi" — kukaan ei estä käyttäjää lähettämästä tietoa palvelimelle vaikkapa omaa ohjelmaa tai Postmania käyttäen.

Saamme sovellukseemme käyttöön myös metoditason auktorisoinnin. Kun konfiguraatiotiedostoon on lisätty annotaatio, on käytössämme muun muassa annotaatio @Secured. Annotaation avulla voidaan määritellä roolit (tai oikeudet), joiden kohdalla annotoidun metodin kutsuminen on sallittua. Alla olevassa esimerkissä post-metodin käyttöön vaaditaan "ADMIN"-oikeudet.

@Secured("ADMIN")
@PostMapping("/posts")
public String post() {
    // ..
    return "redirect:/posts";
}

Esimerkiksi jos käyttäjien tunnistaminen tapahtuu alla olevalla UserDetailsService-rajapinnan olettamalla metodilla, kukaan ei pääse tekemään POST-pyyntöä polkuun /posts.

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Account account = accountRepository.findByUsername(username);
    if (account == null) {
        throw new UsernameNotFoundException("No such user: " + username);
    }

    return new org.springframework.security.core.userdetails.User(
            account.getUsername(),
            account.getPassword(),
            true,
            true,
            true,
            true,
            Arrays.asList(new SimpleGrantedAuthority("USER")));
}

Jos taas roolin tai oikeuden "USER" vaihtaa muotoon "ADMIN", pääsevät kaikki tekemään pyynnön kyseiseen metodiin.

Loading

Annotaatio @Secured määrittelee roolit, joilla metodia voi käyttää. Mikäli sovelluksessa haluaa tehdä tarkempaa tarkastelua, käytetään edellisen sijaan annotaatioita @PreAuthorize ja @PostAuthorize-annotaatioita. Lisää aiheesta mm. Baeldungin oppaassa.

Pääsit aliluvun loppuun! Jatka tästä seuraavaan osaan: