Autentisering och auktorisering
Konfigurera användarautentisering med databaser och definiera åtkomstregler för olika roller och sökvägar.
Autentisering och auktorisering är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
AuthN jämfört med AuthZ
Inom säkerhet talar vi ofta om två centrala begrepp: autentisering och auktorisering.
- Autentisering (AuthN) handlar om att verifiera vem du är. Tänk på det som att visa din legitimation för att bevisa din identitet.
- Auktorisering (AuthZ) handlar om att avgöra vad du får göra när din identitet har bekräftats. Det motsvarar att din legitimation ger dig tillträde till vissa områden.
Autentiseringsflöde med databas
Spring Security kan använda användaruppgifter som lagras i en databas för att autentisera användare. I stället för att hårdkoda användare kan vi ansluta till en riktig datakälla.
Processen omfattar vanligtvis följande:
- En användare försöker logga in.
- Spring Security hämtar användaruppgifter (användarnamn, lösenord och roller) från din databas.
- Det verifierar lösenordet.
- Om allt lyckas är användaren autentiserad.
Hämta användaruppgifter
Det centrala gränssnittet för att hämta användarspecifika data i Spring Security är UserDetailsService. Du implementerar detta för att tala om för Spring hur användare ska hittas i databasen.
Det har en metod: loadUserByUsername(String username). Metoden returnerar ett UserDetails-objekt som innehåller användarens användarnamn, lösenord och behörigheter (roller).
Anpassad UserDetailsService
Nu skapar vi en enkel UserDetailsService. För tillfället simulerar vi hämtning av användare från en lista, men i en riktig applikation skulle detta fråga en databas.
Lägg märke till att vi returnerar ett User-objekt, som är en vanlig implementation av UserDetails.
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Service
public class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
// Simulate users from a database
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}Skydda lösenord
Att lagra lösenord i klartext är en allvarlig säkerhetsrisk. Spring Security kräver att du använder en PasswordEncoder för att hasha (koda) lösenord på ett säkert sätt.
Den vanligaste implementationen är BCryptPasswordEncoder, som använder en stark hash-algoritm. Du definierar denna som en Spring-bean.
Koppla ihop autentiseringen
Nu kopplar vi in vår UserDetailsService och PasswordEncoder i Spring Securitys konfiguration. Vi definierar en SecurityFilterChain-bean.
Den här filterkedjan talar om för Spring hur begäranden ska hanteras, inklusive autentisering.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // Disable CSRF for simplicity in this example
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated() // All other requests require authentication
)
.formLogin(form -> form.permitAll()); // Enable form login for browser access
return http.build();
}
}Fullständigt autentiseringsexempel
Här är en komplett Spring Boot-applikation som demonstrerar grundläggande autentisering med vår anpassade UserDetailsService och PasswordEncoder. Försök att öppna /hello efter att du har loggat in!
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class AuthApp {
public static void main(String[] args) {
SpringApplication.run(AuthApp.class, args);
}
}
@RestController
class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, authenticated user!";
}
}
@Service
class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(form -> form.permitAll());
return http.build();
}
}Vad du får göra
När en användare har autentiserats avgör auktoriseringen vilka resurser eller åtgärder användaren får komma åt eller utföra. Detta görs genom att kontrollera användarens tilldelade roller eller behörigheter.
En användare med rollen "ADMIN" kan till exempel få öppna administrationssidor, medan en användare med rollen "USER" endast kan se sin profil.
Skydda sökvägar efter roll
Med Spring Security kan du definiera auktoriseringsregler direkt i din SecurityFilterChain. Du kan skydda specifika URL-mönster baserat på roller.
Viktiga metoder:
.requestMatchers("/admin/**").hasRole("ADMIN"): Endast användare med rollen 'ADMIN' får komma åt URL:er under/admin/..requestMatchers("/user/**").hasAnyRole("USER", "ADMIN"): Användare med rollen 'USER' eller 'ADMIN'..anyRequest().authenticated(): Alla andra begäranden kräver en autentiserad användare.
AuthZ i praktiken
Nu lägger vi till auktoriseringsregler i vårt föregående exempel. Försök att logga in som 'user' (lösenord: 'password') och 'admin' (lösenord: 'adminpass') och öppna de olika slutpunkterna.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class AuthZApp {
public static void main(String[] args) {
SpringApplication.run(AuthZApp.class, args);
}
}
@RestController
class SecuredController {
@GetMapping("/public")
public String publicPage() {
return "This is a public page.";
}
@GetMapping("/user/profile")
public String userProfile() {
return "Welcome, user! This is your profile.";
}
@GetMapping("/admin/dashboard")
public String adminDashboard() {
return "Welcome, admin! This is the admin dashboard.";
}
}
@Service
class MyUserDetailsService implements UserDetailsService {
private final Map<String, UserDetails> users = new HashMap<>();
public MyUserDetailsService(PasswordEncoder passwordEncoder) {
users.put("user", User.builder()
.username("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build());
users.put("admin", User.builder()
.username("admin")
.password(passwordEncoder.encode("adminpass"))
.roles("ADMIN", "USER")
.build());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = users.get(username);
if (user == null) {
throw new UsernameNotFoundException("User not found: " + username);
}
return user;
}
}
@Configuration
@EnableWebSecurity
class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public").permitAll() // Public access
.requestMatchers("/user/**").hasRole("USER") // Only USER role
.requestMatchers("/admin/**").hasRole("ADMIN") // Only ADMIN role
.anyRequest().authenticated() // All others need authentication
)
.formLogin(form -> form.permitAll());
return http.build();
}
}Snabbtest
Repetera begreppen autentisering och auktorisering samt de komponenter som ingår.
Sammanfattning och nästa steg
Bra jobbat! I den här lektionen har du lärt dig att:
- Skilja mellan autentisering och auktorisering.
- Förstå hur Spring Security använder databaser för autentisering.
- Implementera en anpassad
UserDetailsServiceför att hämta användardata. - Använda
PasswordEncoderför att skydda användarlösenord. - Konfigurera URL-baserade auktoriseringsregler med hjälp av roller.
Härnäst ska du utforska mer avancerade säkerhetsfunktioner, till exempel JWT-baserad autentisering för tillståndslösa API:er!
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 21
- Lektioner
- 84
Vanliga frågor
Är lektionen ”Autentisering och auktorisering” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”Autentisering och auktorisering”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Vad lär jag mig i ”Autentisering och auktorisering”?
Konfigurera användarautentisering med databaser och definiera åtkomstregler för olika roller och sökvägar. Ni övar på Spring Boot 4 – komplett guide med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Spring Boot 4 – komplett guide?
Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Autentisering och auktorisering”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Spring Boot 4 – komplett guide-lektionen?
Ja. Varje Spring Boot 4 – komplett guide-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Grunderna i Spring Security
- Autentisering och auktorisering
- Säkerhet baserad på JWT
- Integration av OAuth2 och social inloggning