Διασφαλίστε την ασφάλεια της εφαρμογής Spring αξιοποιώντας τις ισχυρές δυνατότητες που προσφέρει το πλαίσιο Spring Security.
Το πλαίσιο Spring Security διασφαλίζει την εφαρμογή σας μέσω ελέγχου ταυτότητας και εξουσιοδότησης. Στην προεπιλεγμένη του κατάσταση, το Spring Security διασφαλίζει ότι κάθε διαδρομή αιτήματος HTTP (ή σελίδα) στην εφαρμογή σας απαιτεί τον έλεγχο ταυτότητας ενός μεμονωμένου καθολικού χρήστη.
Αυτό το πλαίσιο είναι επίσης εξαιρετικά ευέλικτο. Σας επιτρέπει να δημιουργείτε προσαρμοσμένους κανόνες ασφαλείας για κάθε διαδρομή αιτήματος HTTP στην εφαρμογή σας, καθώς και για τους διαφορετικούς χρήστες. Έτσι, μπορείτε να καταργήσετε τον περιορισμό ασφαλείας σε σελίδες που δεν απαιτούν εξουσιοδότηση χρήστη (όπως μια αρχική σελίδα). Και ορίστε τους ρόλους και τις εξουσίες συγκεκριμένων τύπων χρηστών.
Προσθήκη Spring Security στην εφαρμογή σας
Υπάρχουν δύο τρόποι για να προσθέσετε την Spring Security στην εφαρμογή σας. Μπορείτε είτε να το επιλέξετε ως εξάρτηση κατά τη δημιουργία μιας νέας εφαρμογής Spring Boot
χρησιμοποιώντας Spring startizrή προσθέστε το στο αρχείο προδιαγραφών κατασκευής στην ενότητα εξάρτησης μετά τη δημιουργία του έργου σας.Εάν επιλέξατε μία από τις επιλογές του έργου Gradle, τότε το αρχείο εξαρτήσεων είναι χτίζω.gradle. Ωστόσο, αν επιλέξατε το Maven, τότε αυτό το αρχείο είναι pom.xml.
Τα δικα σου χτίζω.gradle Το αρχείο πρέπει να περιέχει την ακόλουθη εξάρτηση:
dependencies {
implementation 'org.springframework.boot: spring-boot-starter-security'
}
Ενώ η πom.xml Το αρχείο πρέπει να περιέχει την ακόλουθη εξάρτηση:
org.springframework.boot
spring-boot-starter-security
Το δείγμα εφαρμογής που χρησιμοποιείται στο άρθρο είναι διαθέσιμο σε αυτό Αποθετήριο GitHub και είναι δωρεάν για χρήση βάσει της άδειας MIT.
Χρήση Spring Security
Μόλις προσθέσετε την εξάρτηση Spring Security στην εφαρμογή σας, μπορείτε να αρχίσετε να χρησιμοποιείτε το πλαίσιο αμέσως. Απλώς εκτελέστε την εφαρμογή σας και, στη συνέχεια, μεταβείτε στην αρχική σελίδα του Spring Boot (ή σε οποιαδήποτε σελίδα στην εφαρμογή σας). Το δείγμα εφαρμογής χρησιμοποιεί τον ακόλουθο αρχικό ελεγκτή για τον έλεγχο της προεπιλογής του Spring Boot localhost: 8080 αίτηση:
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclassWebController{
@GetMapping("/")
public String home(){
return"Welcome!";
}
}
Η εκτέλεση της εφαρμογής σας μετά την προσθήκη της παραπάνω κλάσης μεμονωμένου ελεγκτή δημιουργεί την ακόλουθη αρχική προβολή:
Θα παρατηρήσετε ότι σας κατευθύνει αυτόματα στο localhost: 8080/login σελίδα και το κάνει αυτό πριν σας επιτρέψει να αποκτήσετε πρόσβαση σε οποιαδήποτε άλλη σελίδα της εφαρμογής. Σε αυτό το στάδιο, θα χρειαστεί να δώσετε το προεπιλεγμένο όνομα χρήστη (που είναι ο χρήστης) και τον κωδικό πρόσβασης που δημιουργείται αυτόματα (τον οποίο θα βρείτε στην κονσόλα). Η κονσόλα θα δημιουργήσει μια γραμμή όπως η εξής:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
Κάθε φορά που κάνετε επανεκκίνηση της εφαρμογής σας, ο κωδικός που δημιουργείται αυτόματα θα αλλάζει, αλλά το όνομα χρήστη θα παραμένει το ίδιο. Η εισαγωγή του προεπιλεγμένου ονόματος χρήστη και κωδικού πρόσβασης θα σας οδηγήσει στην κατάλληλη προβολή στην εφαρμογή σας.
Προσαρμογή της ασφάλειας της άνοιξης
Για να προσαρμόσετε την ασφάλεια της εφαρμογής σας, θα πρέπει να παρακάμψετε την προεπιλεγμένη διαμόρφωση του Spring Security. Αλλά πριν από αυτό (υποθέτοντας ότι έχετε ήδη Spring Web) θα χρειαστείτε πολλές άλλες εξαρτήσεις για αυτό το δείγμα εφαρμογής:
- Spring Data JPA
- Πρόγραμμα οδήγησης MySQL JDBC
- Θυμόφυλλο
- Lombok
Το πλαίσιο Thymeleaf θα δημιουργήσει διαφορετικές προβολές. Το Lombok θα σας βοηθήσει να μειώσετε τον κώδικα στις κλάσεις αντικειμένων σας. Η βιβλιοθήκη JPA και το πρόγραμμα οδήγησης MySQL θα σας επιτρέψουν να χρησιμοποιήσετε μια βάση δεδομένων MySQL με την εφαρμογή, αλλά έχετε την επιλογή να χρησιμοποιήσετε οποιαδήποτε βάση δεδομένων με την οποία αισθάνεστε άνετα. Η χρήση μιας βάσης δεδομένων σημαίνει τη διαμόρφωση του εφαρμογές.ιδιότητες αρχείο κάτω από το αρχείο πόρων.
spring.datasource.url=jdbc: mysql://${MYSQL_HOST: localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
Ο παραπάνω κώδικας διαμόρφωσης σάς επιτρέπει να συνδεθείτε σε μια τοπική βάση δεδομένων MySQL που ονομάζεται ελατήριο_ασφάλεια, με όνομα χρήστη από ρίζακαι κωδικό πρόσβασης (1234). Θα χρειαστεί να ενημερώσετε αυτά τα δεδομένα ώστε να ταιριάζουν με το όνομα της βάσης δεδομένων και τα διαπιστευτήριά σας.
Αφού προσθέσετε τις πρόσθετες εξαρτήσεις σας και δημιουργήσετε τη βάση δεδομένων σας, μπορείτε να αρχίσετε να αποφασίζετε πόσες προβολές θα έχει η εφαρμογή σας. Θα πρέπει επίσης να γνωρίζετε πώς φαίνεται η ασφάλεια για κάθε σελίδα. Το δείγμα της εφαρμογής μας έχει 6 προβολές:
- Αρχική Σελίδα
- Σελίδα εγγραφής
- Σελίδα σύνδεσης
- Σελίδα αποσύνδεσης
- Σελίδα χρήστη
- Σελίδα σφάλματος
Η μόνη προβολή που απαιτεί εξουσιοδότηση χρήστη είναι η σελίδα χρήστη. Αυτή η σελίδα είναι προσβάσιμη μόνο σε χρήστες που πρώτα εγγράφονται και μετά εισέρχονται στην εφαρμογή. Εκτός από το προεπιλεγμένο πακέτο του Spring Boot, θα χρειαστεί να δημιουργήσετε άλλα τέσσερα πακέτα στην εφαρμογή σας.
Η Τάξη Ελεγκτή Εγγραφής
Το πακέτο ελεγκτή θα περιέχει τις κλάσεις που χειρίζονται αιτήματα HTTP. Ανάλογα με τη λειτουργία μιας σελίδας, μπορείτε συνήθως να ομαδοποιήσετε κάθε αίτημα HTTP σε μία κλάση ελεγκτή, όπως συμβαίνει με το WebController τάξη. Ωστόσο, η προβολή εγγραφής έχει περισσότερες μοναδικές λειτουργίες, επομένως, μπορεί να έχει μια κλάση ιδιωτικού ελεγκτή:
@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
publicRegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder){
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(){
return"registration";
}
@PostMapping
public String processRegistration(RegistrationForm form){
userRepo.save(form.toUser(passwordEncoder));
return"redirect:/login";
}
}
ο RegistrationController class είναι μια πύλη για την πτυχή της ασφάλειας της εφαρμογής σας. ο @RequestMapping Ο σχολιασμός καθορίζει τον τύπο αιτήματος που θα χειριστεί αυτός ο ελεγκτής (αιτήματα προς localhost: 8080/εγγραφή).
ο @GetMapping Ο σχολιασμός απλώς υποδεικνύει ότι εάν η εφαρμογή λάβει αίτημα για /register, ο φόρμα εγγραφής() Η μέθοδος θα πρέπει να χειρίζεται αυτό το αίτημα επιστρέφοντας την προβολή εγγραφής.
Αφού ένας επισκέπτης κάνει κλικ στο κουμπί εγγραφή και, στη συνέχεια, το @PostMapping μπαίνει στο παιχνίδι ο σχολιασμός. ο processRegistration() Η μέθοδος σάς επιτρέπει να δημοσιεύετε τα δεδομένα χρήστη που λαμβάνει από το Φόρμα εγγραφής κλάση στη βάση δεδομένων, χρησιμοποιώντας το UserRepository τάξη. Πριν όμως αποθηκεύσει αυτά τα δεδομένα, το processRegistration() μέθοδος κρυπτογραφεί τον κωδικό πρόσβασης του χρήστη χρησιμοποιώντας της άνοιξηςPasswordEncoder διεπαφή.
Δημιουργία νέων διαμορφώσεων ασφαλείας
Από την Spring 3.1, οι προγραμματιστές μπορούν πλέον να δημιουργούν διαμορφώσεις για την Spring Security χρησιμοποιώντας Java, που σημαίνει κλάσεις αντί για XML. Το κύριο πράγμα που απαιτούν αυτές οι κλάσεις διαμόρφωσης είναι το @Διαμόρφωση σχόλιο.
@Configuration
publicclassSecurityConfiguration{
}
ο @Διαμόρφωση Ο σχολιασμός υποδεικνύει ότι η παραπάνω κλάση είναι μια κλάση διαμόρφωσης. Αυτές οι κατηγορίες παρέχουν φασόλια στο Ανοιξιάτικο πλαίσιο εφαρμογής, το οποίο είναι ένα κοντέινερ που χρησιμοποιεί το Spring για τη δημιουργία και τη διαχείριση των διαφορετικών στοιχείων (ή των φασολιών) μιας εφαρμογής. Το πρώτο φασόλι στο Διαμόρφωση Ασφαλείας τάξη είναι η κωδικοποιητής κωδικού πρόσβασης φασόλι.
@Bean
public PasswordEncoder passwordEncoder(){
returnnew BCryptPasswordEncoder();
}
ο RegistrationController η τάξη χρησιμοποιεί το κωδικοποιητής κωδικού πρόσβασης bean για να κωδικοποιήσετε νέους κωδικούς πρόσβασης πριν τους αποθηκεύσετε στη βάση δεδομένων. Ένα άλλο σημαντικό φασόλι που θα χρειαστεί να προσθέσετε σε Διαμόρφωση Ασφαλείας τάξη είναι η userDetailsService φασόλι.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo){
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
thrownew UsernameNotFoundException("Customer '" + username + "' not found");
};
}
ο userDetailsService φασόλι απασχολεί Ανοιξιάτικη ΑσφάλειαUserDetailsService διεπαφή για την ανάκτηση του ονόματος χρήστη και του κωδικού πρόσβασης ενός χρήστη για έλεγχο ταυτότητας, κατά τη διάρκεια της περιόδου σύνδεσης ενός πελάτη. Έτσι, μόλις ένας πελάτης κάνει κλικ στο κουμπί σύνδεσης στην προβολή σύνδεσης, το userDetailsService φασόλι αναπηδά σε κίνηση.
Μέσα από UserRepository, ο userDetailsService Το bean αποκτά πρόσβαση σε όλους τους υπάρχοντες πελάτες στη βάση δεδομένων. Αυτή η διεπαφή χρησιμοποιεί στη συνέχεια το UserRepository για να εντοπίσετε έναν χρήστη με αντίστοιχο όνομα χρήστη και κωδικό πρόσβασης και, στη συνέχεια, επιστρέφει όλα τα χαρακτηριστικά αυτού του πελάτη ως αντικείμενο.
Εάν το αντικείμενο που επιστρέφεται είναι πελάτης, τότε αυτός ο πελάτης αποκτά πρόσβαση στην εφαρμογή. Διαφορετικά, η σελίδα θα ανανεωθεί αυτόματα επιτρέποντας στον χρήστη να εισάγει έγκυρα διαπιστευτήρια.
Η αλυσίδα του φίλτρου
Ανοιξιάτικη ΑσφάλειαSecurity FilterChain η διεπαφή είναι χρήσιμη διεπαφή προγραμματισμού εφαρμογών (API) που παίζει ουσιαστικό ρόλο στη διαμόρφωση Spring Security. Αυτή η διεπαφή λειτουργεί με Ανοιξιάτικη ΑσφάλειαHttpSecurity τάξη για να δημιουργήσετε μια αλυσίδα φίλτρων για συγκεκριμένα αιτήματα HTTP.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}
ο Αλυσίδα φίλτρου φασόλι παραπάνω χρησιμοποιεί το Security FilterChain API για την ολοκλήρωση πολλών εργασιών. Πρώτον, χρησιμοποιεί το HttpSecurity κλάση για να υπαγορεύσει ότι μόνο οι χρήστες που έχουν το ρόλο του ΧΡΗΣΤΗ μπορούν να έχουν πρόσβαση localhost: 8080/χρήστης. Και ένας χρήστης αποκτά αυτόν τον ρόλο μετά την εγγραφή, χάρη στο getAuthorities() μέθοδο που εφαρμόζει κάθε νέο αντικείμενο πελάτη.
@Override
public Collection extends="extends" grantedauthority="grantedauthority"?> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
Η αλυσίδα φίλτρων επιτρέπει την πρόσβαση χωρίς έλεγχο ταυτότητας σε όλες τις άλλες διευθύνσεις URL της εφαρμογής. ο Αλυσίδα φίλτρου φασόλι χρησιμοποιεί επίσης το formLogin() και Αποσύνδεση() μεθόδους του HttpSecurity αντικείμενο τάξης.
Αυτές οι μέθοδοι σάς επιτρέπουν να κατευθύνετε αυτόματα έναν χρήστη σε συγκεκριμένες σελίδες αφού εκτελέσει μια εργασία. Έτσι, ένας χρήστης που εισάγει τα σωστά διαπιστευτήρια και κάνει κλικ στο κουμπί σύνδεσης στο /login η σελίδα θα κατευθυνθεί αυτόματα στο /user σελίδα.
Τέλος, το Αλυσίδα φίλτρου Το bean δημιουργεί και επιστρέφει την αλυσίδα φίλτρων, η οποία επιτρέπει στους εξουσιοδοτημένους χρήστες να έχουν πρόσβαση στην εφαρμογή. Και τα τρία φασόλια στο Διαμόρφωση Ασφαλείας η τάξη συνεργαστεί για να εξασφαλίσει την αίτησή σας.
Ωστόσο, το Αλυσίδα φίλτρου Το bean παίζει τον πιο σημαντικό ρόλο στην υπαγόρευση του επιπέδου εξουσιοδότησης για κάθε αίτημα HTTP. Καθώς αρχίζετε να προσθέτετε περισσότερες σελίδες στην εφαρμογή σας, μπορείτε να χρησιμοποιήσετε το Αλυσίδα φίλτρου φασόλι για να ορίσετε το επίπεδο ασφάλειάς τους.
Το κύριο όφελος της ασφάλειας της άνοιξης
Η Spring Security σάς δίνει τον πλήρη έλεγχο όχι μόνο για το ποιος έχει πρόσβαση στην εφαρμογή σας, αλλά και για τον τύπο πρόσβασης που μπορεί να έχει ένας χρήστης (μέσω της λειτουργίας ρόλων χρήστη). Ο έλεγχος πρόσβασης είναι μία από τις πιο σημαντικές πτυχές οποιασδήποτε εφαρμογής. Η παροχή αφιλτράριστης πρόσβασης γενικών χρηστών στην εφαρμογή σας λόγω περιορισμένων φραγμών ελέγχου πρόσβασης μπορεί να αποδειχθεί δαπανηρό λάθος.