欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot整合SpringSecurity實現(xiàn)認證攔截的教程

 更新時間:2023年05月11日 11:31:49   作者:一一哥Sun  
我們寫的任何一個項目,都應該有安全防護,不應該讓這個項目進行“裸奔”,否則很容易被別人進行攻擊。而在SpringBoot環(huán)境中,其實可以很容易實現(xiàn)安全保護,本文給大家介紹SpringBoot如何整合SpringSecurity實現(xiàn)認證攔截,需要的朋友可以參考下

一. SpringSecurity簡介

1. SpringSecurity概述

Spring Security 是 Spring 社區(qū)的一個頂級項目,也是 Spring Boot 官方推薦使用的安全框架。

除了常規(guī)的認證(Authentication)和授權(quán)(Authorization)之外,Spring Security還提供了諸如ACLs,LDAP,JAAS,CAS等高級特性以滿足復雜場景下的安全需求。

另外,就目前而言,Spring Security和Shiro也是當前廣大應用使用比較廣泛的兩個安全框架。

Spring Security 應用級別的安全主要包含兩個主要部分,即登錄認證(Authentication)和訪問授權(quán)(Authorization),首先用戶登錄的時候傳入登錄信息,登錄驗證器完成登錄認證并將登錄認證好的信息存儲到請求上下文,然后再進行其他操作,如在進行接口訪問、方法調(diào)用時,權(quán)限認證器從上下文中獲取登錄認證信息,然后根據(jù)認證信息獲取權(quán)限信息,通過權(quán)限信息和特定的授權(quán)策略決定是否授權(quán)。

2. SpringSecurity的特征

  • 對身份驗證和授權(quán)的全面和可擴展的支持;
  • 防止會話固定,點擊劫持,跨站點請求偽造等攻擊;
  • Servlet API集成;
  • 可選與Spring Web MVC集成。

二. SpringBoot整合SpringSecurity實現(xiàn)步驟

1. 需求分析

當用戶來訪問接口時,根據(jù)用戶攜帶的Authorization去查詢此用戶的角色,再根據(jù)設置好的角色所具有的權(quán)限進行判斷,如果訪問的接口是該角色下的接口,則進行接口放行。

2. 創(chuàng)建web項目

我們按照之前的經(jīng)驗,創(chuàng)建一個web程序,并將之改造成Spring Boot項目,具體過程略。

3. 測試未添加SpringSecurity時的情況

我們可以先測試一下項目中不添加Spring Security依賴包的情況,在這種情況下,我直接創(chuàng)建一個Controller接口,然后啟動項目進行測試。

package com.yyg.boot.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 
 * @Date Created in 2020/5/18
 * @Description Description
 */
@RestController
public class IndexController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello SpringSecurity!";
    }

}

4. 創(chuàng)建入口類

package com.yyg.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@SpringBootApplication
public class SecurityApplication {

    public static void main(String[] args){
        SpringApplication.run(SecurityApplication.class,args);
    }

}

5. 訪問接口

此時我們可以看到,在瀏覽器中可以直接訪問這個接口方法。

6. 添加Spring Security依賴包

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

7. 重啟項目測試

當添加了spring-boot-starter-security依賴包之后,我們此時再重新啟動項目進行測試。此時會發(fā)現(xiàn)控制臺中有一行日志信息:也就是Spring Boot會自動產(chǎn)生一個隨機的密碼。

然后我們再訪問剛才的接口,會發(fā)現(xiàn)接口會自動重定向到login登錄頁面。

然后在這個登錄頁面中,我們可以輸入用戶名和密碼:

  • 用戶名:user
  • 密碼:控制臺的隨機密碼

然后此時才可以看到剛才的接口內(nèi)容。

這是因為當Spring項目中引入了Spring Security依賴的時候,項目會默認開啟如下配置:

security.basic.enabled=true

這個配置開啟了一個表單認證,所有服務的訪問都必須先過這個認證,默認的用戶名為user,密碼由Sping Security自動生成,回到IDE的控制臺,可以找到密碼信息:

Using generated security password: 078db2a5-ae07-4a10-a85c-cf0162a7e966

8. 修改登錄表單的用戶名和密碼

我們可以在application.yml文件中,通過spring.security屬性進行用戶名和密碼的配置。

server:
  port: 8080
spring:
  security:
    user:
      name: admin
      password: 123

此時可以看到,新的登錄名和密碼變成了我們設置好的。

三. 基于HttpBasic認證

1. HttpBasic認證實現(xiàn)

配置SpringSecurity認證方式。
創(chuàng)建一個配置類SpringSecurityConfig繼承org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter這個抽象類并重寫configure(HttpSecurity http)方法。

WebSecurityConfigurerAdapter是由Spring Security提供的Web應用安全配置的適配器:

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()                // HttpBasic
//        http.formLogin()              // 表單方式
                .and()
                .authorizeRequests()  // 授權(quán)配置
                .anyRequest()         // 所有請求
                .authenticated();     // 都需要認證
    }
}

HttpBasic登錄效果

2. HttpBasic基本原理

上面我們開啟了一個最簡單的Spring Security安全配置,下面我們來了解下Spring Security的基本原理。通過上面的的配置,代碼的執(zhí)行過程可以簡化為下圖表示:

如上圖所示,Spring Security包含了眾多的過濾器,這些過濾器形成了一條鏈,所有請求都必須通過這些過濾器后才能成功訪問到資源。

其中UsernamePasswordAuthenticationFilter過濾器用于處理基于表單方式的登錄認證,而BasicAuthenticationFilter用于處理基于HTTP Basic方式的登錄驗證,后面還可能包含一系列別的過濾器(可以通過相應配置開啟)。

在過濾器鏈的末尾是一個名為FilterSecurityInterceptor的攔截器,用于判斷當前請求身份認證是否成功,是否有相應的權(quán)限,當身份認證失敗或者權(quán)限不足的時候便會拋出相應的異常。ExceptionTranslateFilter捕獲并處理,所以我們在ExceptionTranslateFilter過濾器用于處理了FilterSecurityInterceptor拋出的異常并進行處理,比如需要身份認證時將請求重定向到相應的認證頁面,當認證失敗或者權(quán)限不足時返回相應的提示信息。

四. SpringBoot集成SpringSecurity實現(xiàn)權(quán)限管理

我們在上面案例的基礎(chǔ)上,進行本案例的開發(fā)講解。

1. 創(chuàng)建實體類

1.1 創(chuàng)建Admin實體類

package com.yyg.boot.domain;

import lombok.Data;

import java.io.Serializable;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@Data
public class Admin implements Serializable {

    private String username;

    private String password;

}

1.2 創(chuàng)建Member實體類

package com.yyg.boot.domain;

import lombok.Data;

import java.io.Serializable;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@Data
public class Member implements Serializable {

    private String id;

    private String username;

    private String password;

}

2. 繼承WebSecurityConfigurerAdapter配置角色權(quán)限

package com.yyg.boot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    //@Override
    //protected void configure(HttpSecurity http) throws Exception {
        //http.httpBasic()                // 簡單的HttpBasic登錄方式
        //http.formLogin()              // 提供一個登錄的表單
                //.and()
                //.authorizeRequests()  // 授權(quán)配置
                //.anyRequest()         // 所有請求
                //.authenticated();     // 都需要認證
    //}

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    //內(nèi)存方式創(chuàng)建用戶
//    @Override
//    public void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication()
//                .withUser("admin").password("123456").roles("ADMIN")
//                .and()
//                .withUser("member").password("123456").roles("MEMBER");
//    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                //passwordEncoder是對密碼的加密處理,如果user中密碼沒有加密,則可以不加此方法。注意加密請使用security自帶的加密方式。
                .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                //禁用了 csrf 功能
                .disable()
                //限定簽名成功的請求
                .authorizeRequests()
                .antMatchers("/employee/*")
                //對employee 下的接口,需要 MEMBER 或者 ADMIN 權(quán)限
                .hasAnyRole("MEMBER","ADMIN")
                //對employee/login接口直接放行,不限制
                .antMatchers("/employee/login")
                .permitAll()
                //對admin下的接口 需要ADMIN權(quán)限
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                //不攔截 oauth 開放的資源
                .antMatchers("/oauth/**")
                .permitAll()
                //其他沒有限定的請求,允許訪問
                .anyRequest()
                .permitAll()
                .and()
                //對于沒有配置權(quán)限的其他請求允許匿名訪問
                .anonymous()
                .and()
                //使用 spring security 默認登錄頁面
                .formLogin()
                .and()
                //啟用http 基礎(chǔ)驗證
                .httpBasic();
    }

}

3. 創(chuàng)建UserDetailsService

package com.yyg.boot.service;

import com.yyg.boot.domain.Admin;
import com.yyg.boot.domain.Member;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author 
 * @Date Created in 2020/5/18
 * @Description Description
 */
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

        //生成環(huán)境是查詢數(shù)據(jù)庫獲取username的角色用于后續(xù)權(quán)限判斷(如:張三 admin)
        //這里不做數(shù)據(jù)庫操作,給定假數(shù)據(jù),進行簡單模擬.
        if ("member".equals(username)) {
            Member member = new Member();
            member.setUsername("member");
            member.setPassword("123456");
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_MEMBER");
            grantedAuthorities.add(grantedAuthority);
            //創(chuàng)建一個用戶,用于判斷權(quán)限,請注意此用戶名和方法參數(shù)中的username一致;BCryptPasswordEncoder是用來演示加密使用。
            return new User(member.getUsername(), new BCryptPasswordEncoder().encode(member.getPassword()), grantedAuthorities);
        }

        if ("admin".equals(username)) {
            Admin admin = new Admin();
            admin.setUsername("admin");
            admin.setPassword("123456");
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
            grantedAuthorities.add(grantedAuthority);
            return new User(admin.getUsername(), new BCryptPasswordEncoder().encode(admin.getPassword()), grantedAuthorities);
        } else {
            return null;
        }

    }

}

4. 創(chuàng)建controller層代碼

4.1 創(chuàng)建AdminController

package com.yyg.boot.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@RestController
@RequestMapping("/admin")
public class AdminController {

    @GetMapping("/greeting")
    public String greeting() {
        return "Hello,Admin!";
    }

    @GetMapping("/login")
    public String login() {

        return "login success!";
    }

}

4.2 創(chuàng)建MemberController

package com.yyg.boot.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/5/18
 * @Description Description
 */
@RestController
@RequestMapping("/member")
public class MemberController {

    @GetMapping("/greeting")
    public String greeting() {
        return "Hello,Member!";
    }

    @GetMapping("/login")
    public String login() {

        return "login success!";
    }

}

5. 進行測試

此時我們可以利用postman,通過Basic認證方式,攜帶用戶名和密碼進行相關(guān)接口的訪問。

5.1 member身份的權(quán)限,只能訪問member相關(guān)的接口:

5.2 admin身份的權(quán)限,可以訪問admin與member相關(guān)的接口:

后續(xù)我們可以關(guān)聯(lián)數(shù)據(jù)庫,從數(shù)據(jù)庫中查詢用戶的身份和角色信息,從而進一步給用戶分配權(quán)限信息。

結(jié)語

至此,我們就對Web項目添加了一個安全防護,而且實現(xiàn)起來簡直不要太easy!現(xiàn)在你知道該怎么保護自己的Web項目不被“傷害”了嗎?

以上就是SpringBoot整合SpringSecurity實現(xiàn)認證攔截的教程的詳細內(nèi)容,更多關(guān)于SpringBoot整合SpringSecurity實現(xiàn)認證攔截的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java內(nèi)存優(yōu)化的方法總結(jié)

    java內(nèi)存優(yōu)化的方法總結(jié)

    在本篇文章里小編給大家分享的是一篇關(guān)于java內(nèi)存優(yōu)化的方法總結(jié)內(nèi)容,有需要的朋友們可以學習下。
    2021-06-06
  • 解決Java J2EE亂碼問題的方法

    解決Java J2EE亂碼問題的方法

    這篇文章主要為大家詳細介紹了解決Java J2EE亂碼問題的方法的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • 如何解決java.util.zip.ZipFile解壓后被java占用問題

    如何解決java.util.zip.ZipFile解壓后被java占用問題

    這篇文章主要介紹了如何解決java.util.zip.ZipFile解壓后被java占用問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Spring Task定時任務的配置和使用詳解

    Spring Task定時任務的配置和使用詳解

    本篇文章主要介紹了Spring Task定時任務的配置和使用詳解,實例分析了Spring Task定時任務的配置和使用的技巧,非常具有實用價值,需要的朋友可以參考下
    2017-04-04
  • Intellij IDEA安裝lombok插件及使用詳解

    Intellij IDEA安裝lombok插件及使用詳解

    今天小編就為大家分享一篇關(guān)于Intellij IDEA安裝lombok插件及使用詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Kotlin實現(xiàn)靜態(tài)方法

    Kotlin實現(xiàn)靜態(tài)方法

    這篇文章主要介紹了Kotlin實現(xiàn)靜態(tài)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Spring Boot 控制層之參數(shù)傳遞方法詳解

    Spring Boot 控制層之參數(shù)傳遞方法詳解

    這篇文章主要介紹了Spring Boot 控制層之參數(shù)傳遞方法詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • 完整B樹算法Java實現(xiàn)代碼

    完整B樹算法Java實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了完整的B樹算法Java實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解Java如何通過Socket實現(xiàn)查詢IP

    詳解Java如何通過Socket實現(xiàn)查詢IP

    在本文中,我們來學習下如何找到連接到服務器的客戶端計算機的IP地址。我們將創(chuàng)建一個簡單的客戶端-服務器場景,讓我們探索用于TCP/IP通信的java.net?API,感興趣的可以了解一下
    2022-10-10
  • 關(guān)于Java?獲取時間戳的方法

    關(guān)于Java?獲取時間戳的方法

    這篇文章主要介紹了關(guān)于Java獲取時間戳的方法,Java有兩個取時間戳的方法,分別是System.currentTimeMillis()和System.nanoTime()下文對兩種方法進行詳細介紹,需要的小伙伴可以參考一下
    2022-04-04

最新評論