最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security常用配置的使用解讀

 更新時間:2025年06月07日 08:49:40   作者:lukamao  
這篇文章主要介紹了Spring Security常用配置的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Spring Security 是 Spring 家族為我們提供的一款安全管理的框架,它是一個功能強大并且可以靈活定制的身份驗證和訪問控制框架。Spring Security 側(cè)重于為 Java 應(yīng)用程序提供身份驗證和授權(quán)。與所有 Spring 項目一樣,Spring Security 的真正強大之處在于它非常容易擴展來滿足我們的不同需求。

在 SSM 時代,Spring Security 因為繁瑣的配置而不被人們常用,但是在 Spring Boot 中為提供了自動化配置方案,可以零配置使用 Spring Security。

初體驗

在 pom.xml 中導(dǎo)入 maven 依賴

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

只要在項目中加入 Spring Security 的依賴,項目中的所有接口都會被保護起來了。

當我們訪問我們的項目的時候,就會先來到 Spring Security 默認的登錄頁面,

默認的用戶名是 user,密碼會在控制臺打印,

登錄后就可以正常訪問項目了。

自定義用戶名密碼

因為密碼是隨機生成的一段密鑰,不方便記憶,所以我們可以自己配置用戶名和密碼。

配置用戶名和密碼的方式有三種,我們可以在配置文件中配置,也可以在 Java 代碼中配置,還可以在數(shù)據(jù)庫中配置,我們先看如何在配置文件中配置。

使用配置文件配置

使用配置文件配置比較簡單,直接在 application.yml 中配置即可。

spring:
  security:
    user:
      name: user
      password: 1234

使用 Java 代碼配置

使用 Java 代碼配置也比較簡單,我們只需要編寫一個 SecurityConfig 配置類,重寫一個 configure() 方法即可。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("$2a$10$zwUhw4cAEv1AH6auayRPbePJAKk87peABiKegNMp4mqKXWxJZyDQS").roles("user")
                .and()
                .withUser("admin").password("$2a$10$mDQiCHTt3RLV.pLozBKOBOVIe7kaa3vYUCqZUu.957mpomdztOr0y").roles("admin");
    }

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

使用 Java 代碼配置比較靈活,我們可以用 and() 方法來配置多個用戶。

在 Spring 5 以后要求我們配置的密碼必須是加密的,我們可以配置一個 BCryptPasswordEncoder 密碼編碼器來幫助我們加密密碼,我們只需要在單元測試中創(chuàng)建一個 BCryptPasswordEncoder 密碼編碼器,調(diào)用它的 encode()方法來加密,把得到的值復(fù)制到代碼中,然后再將這個密碼編碼器配置到容器中,這個密碼編碼器的的好處是即使是相同的字段也可以得到不同的結(jié)果。

自定義攔截規(guī)則

因為 Spring Security 默認攔截所有的請求,但我們實際項目中肯定不能這樣,所以我們應(yīng)該自定義攔截規(guī)則,針對不同的請求,制定不同的處理方式。

這就需要用到 HttpSecurity 的配置,我們只需要在配置類中實現(xiàn)重載的 configure() 方法

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()  // 驗證請求
            	// 路徑匹配,參數(shù)是要處理的 url
                .antMatchers("/admin/**").hasRole("admin")  // 要具有某種權(quán)限
                .antMatchers("/user/**").hasAnyRole("admin", "user")// 要具有某種權(quán)限中的一種
                .anyRequest().authenticated();
    }
    
}

登錄注銷配置

Spring Security 為我們提供的絕不止上面的那么簡單,我們通過配置 HttpSecurity 還可以定制登錄接口,登錄成功后的響應(yīng),登錄失敗后的響應(yīng)以及注銷的相關(guān)操作。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .formLogin()
            	// 登錄處理接口
                .loginProcessingUrl("/login")
            	// 定義登錄頁面,未登錄時,訪問一個需要登錄之后才能訪問的接口,會自動跳轉(zhuǎn)到該頁面
                .loginPage("/login")
            	// 定義登錄時,用戶名的 key,默認為 username
                .usernameParameter("uname")
            	// 定義登錄時,用戶密碼的 key,默認為 password
                .passwordParameter("passwd")
            	// 登錄成功的處理器
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 200);
                        map.put("msg", authentication.getPrincipal());
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
            	// 登錄失敗的處理器
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 401);
                        if (e instanceof LockedException) {
                            map.put("msg", "賬戶被鎖定,登錄失敗!");
                        } else if (e instanceof BadCredentialsException) {
                            map.put("msg", "用戶名或密碼輸入錯誤,登錄失?。?);
                        } else if (e instanceof DisabledException) {
                            map.put("msg", "賬戶被禁用,登錄失??!");
                        } else if (e instanceof AccountExpiredException) {
                            map.put("msg", "賬戶過期,登錄失??!");
                        } else if (e instanceof CredentialsExpiredException) {
                            map.put("msg", "密碼過期,登錄失??!");
                        } else {
                            map.put("msg", "登錄失??!");
                        }
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
            	// 和表單登錄相關(guān)的接口統(tǒng)統(tǒng)都直接通過
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
            	// 注銷成功的處理器
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 200);
                        map.put("msg", "注銷登錄成功!");
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                });
    }

}

方法安全

Spring Security 還為我們提供了方法級別安全的配置,什么是方法安全呢?就是在調(diào)用方法的時候來進行驗證和授權(quán)。怎么實現(xiàn)方法安全呢?

首先我們要在配置類上加一個注解 @EnableGlobalMethodSecurity,

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}

并將 prePostEnabled 和 securedEnabled 兩個屬性值設(shè)置為 true,接下來就可以在方法上加注解來進行權(quán)限控制了。

我們先寫一個 MethodService

@Service
public class MethodService {

    @PreAuthorize("hasRole('admin')")
    public String admin() {
        return "hello admin";
    }
    @Secured("ROLE_user")
    public String user() {
        return "hello user";
    }
    @PreAuthorize("hasAnyRole('admin', 'user')")
    public String hello() {
        return "hello hello";
    }

}

用@PreAuthorize 注解和@Secured 注解來控制方法的訪問權(quán)限,再寫一個 HelloController

@RestController
public class HelloController {

    @Autowired
    MethodService methodService;

    @GetMapping("hello1")
    public String hello1() {
        return methodService.admin();
    }
    @GetMapping("hello2")
    public String hello2() {
        return methodService.user();
    }
    @GetMapping("hello3")
    public String hello3() {
        return methodService.hello();
    }

}

此時啟動項目,我們用 admin 登錄,分別發(fā)送 hello1,hello2,hello3 請求

hello1 請求能夠訪問

因為配置了 user() 方法要具有 user 權(quán)限才能訪問,所以報 403 錯誤

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java多線程volatile原理及用法解析

    Java多線程volatile原理及用法解析

    這篇文章主要介紹了Java多線程volatile原理及用法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-07-07
  • java中isEmpty和isBlank的區(qū)別小結(jié)

    java中isEmpty和isBlank的區(qū)別小結(jié)

    Java中的isEmpty和isBlank都是用來判斷字符串是否為空的方法,但在不同的情況下有所區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Java?泛型的上界和下界通配符示例詳解

    Java?泛型的上界和下界通配符示例詳解

    這篇文章主要為大家通過示例介紹了Java?泛型的上界和下界通配符,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)

    jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)

    這篇文章主要介紹了jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java工具類StringUtils使用實例詳解

    java工具類StringUtils使用實例詳解

    這篇文章主要為大家介紹了java工具類StringUtils使用實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • JPA?@ManyToMany?報錯StackOverflowError的解決

    JPA?@ManyToMany?報錯StackOverflowError的解決

    這篇文章主要介紹了JPA?@ManyToMany?報錯StackOverflowError的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java中jdbcTemplate的queryForList(坑)

    java中jdbcTemplate的queryForList(坑)

    本文主要介紹了java中jdbcTemplate的queryForList,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java基礎(chǔ)學(xué)習之接口詳解

    Java基礎(chǔ)學(xué)習之接口詳解

    接口,是Java語言中一種引用類型,是方法的集合,如果說類的內(nèi)部封裝了成員變量、構(gòu)造方法和成員方法,那么接口的內(nèi)部主要就是封裝了方法。本文通過一些示例詳細為大家展示了接口的使用,需要的可以參考一下
    2022-10-10
  • Java引用類型interface的用法總結(jié)

    Java引用類型interface的用法總結(jié)

    這篇文章主要為大家詳細介紹了Java中引用類型interface的用法的相關(guān)資料,文中的示例代碼講解詳細,對我們學(xué)習Java有一定幫助,感興趣的可以了解一下
    2022-10-10
  • JavaFx實現(xiàn)拼圖游戲

    JavaFx實現(xiàn)拼圖游戲

    這篇文章主要為大家詳細介紹了JavaFx實現(xiàn)拼圖游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09

最新評論

平安县| 南丰县| 南召县| 古浪县| 钟山县| 板桥市| 卢龙县| 莱州市| 浦东新区| 浙江省| 宝山区| 小金县| 泰和县| 平南县| 巴里| 湟中县| 伊金霍洛旗| 昌吉市| 三门县| 犍为县| 铅山县| 六枝特区| 嘉义县| 德化县| 咸宁市| 兴山县| 固镇县| 丹寨县| 海林市| 保山市| 东阿县| 吉林省| 景泰县| 永吉县| 剑河县| 都兰县| 昌宁县| 桑植县| 巴里| 柳州市| 岳西县|