Artikel ini menceritakan kisah Spring Boot mengintegrasikan keamanan musim semi untuk mengimplementasikan kontrol izin menggunakan anotasi pada metode, dan menggunakan UserDetailService khusus untuk memuat informasi pengguna dari MySQL. Gunakan enkripsi MD5 yang dilengkapi dengan keamanan untuk mengenkripsi kata sandi pengguna. Template halaman menggunakan mesin Thymeleaf.
Alamat Kode Sumber: https://github.com/li5454yong/springboot-security.git
1. Memperkenalkan dependensi pom
<partent> <groupid> org.springframework.boot </groupid> <ArtifactId> Spring-boot-starter-parent </arttifactid> <version> 1.4.4.release </version> </boot/groupiD> <sgroupid> <sroupid> org.springframework.boot/groupid> <sgroupcid> <sroupid> </Dependency> <dependency> <GroupId> org.springframework.boot </groupid> <ArtiFacTId> Spring-boot-starter-Security </arttifactid> </gandendency> <sgrouptid> <Roupid> <trupponency> <tampaCh-security. <dependency> <GroupId> org.springframework.boot </groupid> <ArtifactId> Spring-boot-starter-thymeleaf </artifactid> </dependency> <sependency> <roupid> org.springframework.boot </groupid> <t Artifactid> <trotif-boots-starterter.bootpa </groupid> <t Artifactid> Spring-boots-starard.bootpa </groupid> <t Artifactid> Spring-boot-starard <groupId> org.springframework.boot </groupid> <ArTifactId> Spring-boot-starter-jdbc </arttifactid> </dependency> <dependency> <groupid> MySQL </groupid> <ArtifactId> MySQL-Connector-java </Artifactid> <artifactid> MySQL-connector-java </arttifactid> <artifactid> MySQL-connector-java </arttifactid> <artifactid> MySQL-Connector-java </arttifactid> <artifactid> MySQL-connector-java </arttifactid> <artefactid> MySQL-Connector-java </Artifactid> <conperence> 5.11.111 <groupid> com.alibaba </groupId> <ArTifactId> druid </t Artifactid> <version> 1.0.15 </version> </gandendency> </dependencies>
Di sini, gunakan pengumpulan koneksi Druid, dan data pegas JPA mengimplementasikan akses database.
2. Konfigurasikan keamanan musim semi
@Configuration @enableWebMvcsecurity @enableGlobalmethodsecurity (preposteNabled = true) // aktifkan annotasi keamanan kelas publik websecurityconfig memperluas websecurityconfigurerAdapter {@bean @Override ProtecticationManagerManagerManager () throwon {@bean @Override AuthentIcationManagerManager () throwon {@bean @Override authenticationManagerManager () throwon {@Bean @Override authenticationManagerManager () throwse {@bean {return {return {return {return {return {return {return {return. } @Override void void configure (httpsecurity http) melempar pengecualian {// memungkinkan semua pengguna untuk mengakses "/" dan "/home" http.authorizeRequests () .AntMatchers ("/", "/home"). AUTROLAD () // akses ke alamat lain yang memerlukan verifikasi lain. // Tentukan halaman login menjadi "/login" .loginpage ("/login") .defaultSucCessUrl ("/hello") // Setelah login berhasil, lompat ke "/hello" secara default. .permitall () .and () .logout () .logoutsuccessurl ("/home") // URL default setelah keluar adalah "/home" .permitall (); } @Autowired public void configureglobal (authenticationManagerBuilder auth) melempar Exception {auth .userDetailsService (customUserDetailsService ()) .passwordEncoder (kata sandicoder ()); } / *** Atur metode enkripsi kata sandi pengguna ke enkripsi MD5* @return* / @bean public md5passwordEncoder passwordEncoder () {return md5passwordEncoder baru (); } / *** UserDetailSService khusus untuk membaca informasi pengguna dari database* @return* / @bean public customUserDetailsService customUserDetailsService () {return customUserDetailService () baru (); }} Hanya konfigurasi dasar yang dibuat di sini, menyiapkan URL login, URL yang melompat setelah login berhasil, dan URL yang melompat ke setelah logout. Menggunakan anotasi @EnableGlobalMethodSecurity (prepostenabled = true) dapat memungkinkan anotasi keamanan. Kita dapat menggunakan @preauthorize dan @prefilter pada metode yang memerlukan izin kontrol.
3. UserDetailService khusus
Kelas Publik CustomUserDetailSService mengimplementasikan userDetailsService {@Autowired // Kelas Layanan Domain Private Suserservice WaitService; @Override Public UserDetails LoadUserByUserName (String Username) melempar UsernamenotFoundException {// Suser sesuai dengan tabel pengguna dalam database, yang merupakan tabel yang pada akhirnya menyimpan pengguna dan kata sandi, yang dapat disesuaikan // Contoh ini menggunakan email dalam SUSER sebagai nama pengguna: SUSER USER = SUSERSERVICE. if (user == null) {lempar UsernamenotFoundException baru ("nama pengguna" + nama pengguna + "tidak ditemukan"); } // SecurityUser mengimplementasikan UserDetails dan Peta email Suser ke Username SecurityUser SecurityUser = New SecurityUser (pengguna); Koleksi <MenementGrantEdAuthority> Otoritas = Daftar Arraylist Baru <MenemeGrantEdAuthority> (); Otorities.Add (new SimpleGrantEdAuthority ("Role_admin")); Return SecurityUser; }}Di sini Anda hanya perlu mengimplementasikan antarmuka UserDetailsService, menulis ulang metode LoadUserbyUserName, dan mengambil informasi pengguna dari database. Akhirnya, kelas implementasi pengguna dikembalikan.
4. Tentukan konfigurasi penanganan kesalahan
@ConfigurationPublic kelas errorPageconfig {@Bean embeddedServletContainerCustomizer publik embeddedServletContainerCustomizer () {return new mycustomizer (); } private static class mycustomizer mengimplementasikan embeddedservletcontainercustomizer {@Override public void customize (configurableembeddedServletContainer container) {container.adderrorpages (new errorPage (httpstatus.forbidden, "/403")); }}}Saat kesalahan akses terjadi, lompat ke "/403".
5. Antarmuka pengontrol
@ControllerPublic Class IndexController {@resource private Suserservice Suserservice; @RequestMapping ("/home") public string home () {return "home"; } @PreAuthorize ("HasRole ('User')") @RequestMapping (value = "/admin", Method = requestMethod.get) public String toAdmin () {return "helloadmin"; } @RequestMapping ("/hello") Public String Hello () {return "Hello"; } @RequestMapping ("/Login") Public String Login () {return "Login"; } @RequestMapping ("/") public string root () {return "index"; } @RequestMapping ("/403") Public String error () {return "403"; }}@Preauthorize ("hasrole ('user')") digunakan pada metode toadmin (), menunjukkan bahwa Anda perlu memiliki peran pengguna untuk mengakses metode ini. Jika Anda ingin mengontrol level izin, Anda dapat menggunakan @preauthorize ("haspermission ()"). Ini hanya salah satu penggunaan. Untuk metode penggunaan lebih lanjut, Anda dapat membaca dokumentasi resmi. Perlu dicatat bahwa awalan peran default dari Spring Security adalah "Role_", yang telah ditambahkan secara default saat menggunakan metode Hasrole. Oleh karena itu, peran pengguna kami dalam database harus "Role_user", dan awalan pengguna "Role_" ditambahkan sebelum pengguna.
6. Tes
Mulai proyek dan kunjungi http: // localhost: 1130/login
Klik untuk Masuk dan Masukkan "/Halo"
Klik untuk melompat ke halaman Administrator
Di URL "/admin" yang sesuai dengan metode "pengguna", pengguna harus memiliki peran "pengguna". Pengguna yang masuk juga ditetapkan dalam database untuk memiliki peran ini.
Sekarang kami memodifikasi peran pengguna dalam database dan mengubahnya menjadi "role_admin". Setelah keluar, masuk lagi, klik tombol "Pergi ke Halaman Administrator" lagi, dan itu akan melompat ke halaman berikut.
Karena tidak ada izin "pengguna" sekarang, pengecualian dilemparkan selama akses, dan dicegat dan dialihkan ke "/403".
7. Posting Akses, Kode Kesalahan 403
Pertama, ubah "/admin" untuk memposting permintaan
@PreAuthorize ("HasRole ('User')") @RequestMapping (value = "/admin", Method = requestMethod.post) Public String ToAdmin () {return "Helloadmin"; }Ubah Metode Permintaan tombol "Buka Halaman Administrator" dari Formulir Asli Get Submission ke Ajax Post Submission. Adapun mengapa kami tidak dikirimkan menggunakan Form Post, kami akan membicarakannya nanti. Ubah kode terlebih dahulu
<hody> <h1 th: inline = "text"> hello [[$ {#httpservletrequest.remoteUser}]]! </h1> <!-<bentuk th: action = "@{/logout}" get = "POST"> <input type = "kirim" value = "mogok keluar"/</formulir " TH: type = "Kirim" th: value = "Pergi ke halaman administrator"/> </form>-> <a th: href = "@{/admin}" rel = "eksternal nofollow"> buka halaman pengguna administrator </a> <input th: type = "kirim" onclick = "testpost ()" test = "go go to the administration> {function> {function> {function> {function> {function> {function> {function> $ .AJAX ({url: "/admin", ketik: 'Post', Success: function (data) {}}); } </script> Klik tombol "Pergi ke Halaman Administrator", dan Anda dapat melihat yang berikut di Platform Debugging
Ini karena kerangka kerja mencegah CSRF (pemalsuan pemalsuan lintas situs-cross-situs, pemalsuan) dari terjadi, membatasi sebagian besar metode kecuali Get.
Ini solusi:
Pertama tambahkan konten berikut dalam tag.
<meta name = "_ csrf" th: content = "$ {_ csrf.token}"/> <meta name = "_ csrf_hader" th: content = "$ {_ csrf.HeaderName}"//> Selama token ini ditambahkan, latar belakang akan memverifikasi kebenaran token ini. Jika benar, itu akan menerima akses pos.
Kemudian tambahkan kode berikut dalam kode AJAX:
var token = $ ('meta [name = "_ csrf"]'). attr ("content"); var header = $ ('meta [name = "_ csrf_hader"]'). attr ("content"); $ (dokumen) .AjaxSend (function (e, xhr, opt) {xhr.set.setre (function (e, xhr, opt) {xhr.set.setre (function (e, xhr, opt) {xhr.set.setre (function (e, xhr, opt) {xhr.set.setre (function (e, xhr, opt) {xhr.set.setRe Dengan cara ini, Anda dapat mengaksesnya secara normal menggunakan metode POST, DELETE, dan lainnya.
Yang disebutkan di atas menggunakan metode POST formulir untuk dikirim. Anda dapat melihat dengan melihat kode sumber halaman.
Kerangka kerja secara otomatis memasukkan bidang tersembunyi ke dalam formulir formulir, dan nilai nilai adalah token itu, jadi menggunakan formulir formulir untuk mengirimkan permintaan pos dapat dilewati secara langsung, dan jika Anda mengirimkannya dengan cara Ajax, kode itu perlu ditambahkan.
Oke, itu semua tentang artikel ini. Akan ada artikel nanti tentang cara menggunakan keamanan musim semi untuk mengendalikan izin dalam gaya API REST.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.