Spring Security入門教程 通俗易懂 超詳細 【內含案例】


Spring Security的簡單使用

推薦 Java 常見面試題

簡介

  • SSM 整合 Security 是比較麻煩的,雖然Security的功能比 Shiro 強大,相反卻沒有Shiro的使用量多
  • SpringBoot出現后簡化了Spring系列的配置文件,因此SpringSecurity的使用逐漸增加

一、創建項目

查看代碼

在 SpringBoot 中直接引入 Spring Security 依賴即可

image

創建項目的啟動類

image

創建 SecurityController 類

image

  • 啟動后訪問 localhost:8080/hello
  • 會自動跳到 localhost:8080/login
  • 需要登錄后才能訪問 /hello

image

二、用戶名配置

查看代碼

  • 默認情況下用戶名是 user ,而密碼會在項目啟動時 控制台 打印出一串隨機 字符串,這就是密碼.每次啟動項目,密碼都不一樣

image

  • 對登錄的用戶名/密碼進行配置,有三種不同的方式
  1. application 配置文件中聲明
  2. java 代碼配置在內存里
  3. 通過獲取 數據庫

第一種方式 application.yml 文件中

image

第二種方式 創建一個SecurityConfig配置類,繼承 WebSecurityConfigurerAdapter

image

第三種方法沒有進行演示,就是在數據庫中取出usernamepassword配置到內存中

三、忽略攔截

查看代碼

image

在配置類中重寫 configure(WebSecurity web) 方法,然后直接訪問即可

image

pom.xml文件

返回閱讀

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--Web項目 需引入web依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
啟動類文件
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@SpringBootApplication
public class SecurityApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class, args);
    }
}
SecurityController 文件
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@RestController
public class SecurityController {

    /**
     * 不用登錄就可訪問
     * @return
     */
    @RequestMapping("/hi")
    public String sayHi(){
        return "Hi bro!";
    }

    @RequestMapping("/hello")
    public String sayHello(){
        return "Hello bro!";
    }
}
application.yml 配置文件

返回閱讀

spring:
  security:
    user:
      name: beixuan
      password: beixuan
SecurityConfig Java配置文件

此方法配置用戶與配置 yml 文件效果一致

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.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //Spring Security5之后 官方需要密碼強制加密,如不想加密可創建一個過期的 PasswordEncoder 的實例 NoOpPasswordEncoder,但不安全
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode("beixuan");
        //添加一個用戶[beixuan] 角色為[admin] 密碼是[beixuan加密后的密鑰]
        auth.inMemoryAuthentication()
                .withUser("beixuan")
                .roles("admin")
                .password(password);
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
  • 具體的登錄配置 下面代碼借鑒於 江南一點雨 隨筆的代碼,有興趣可以看看
  • VerifyCodeFilter 一次性驗證碼,可以查看資料了解其使用方法,這里不再敘述
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    VerifyCodeFilter verifyCodeFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
        http
        .authorizeRequests()//開啟登錄配置
        .antMatchers("/hello").hasRole("admin")//表示訪問 /hello 這個接口,需要具備 admin 這個角色
        .anyRequest().authenticated()//表示剩余的其他接口,登錄之后就能訪問
        .and()
        .formLogin()
        //定義登錄頁面,未登錄時,訪問一個需要登錄之后才能訪問的接口,會自動跳轉到該頁面
        .loginPage("/login_p")
        //登錄處理接口
        .loginProcessingUrl("/doLogin")
        //定義登錄時,用戶名的 key,默認為 username
        .usernameParameter("uname")
        //定義登錄時,用戶密碼的 key,默認為 password
        .passwordParameter("passwd")
        //登錄成功的處理器
        .successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("success");
                    out.flush();
                }
            })
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("fail");
                    out.flush();
                }
            })
            .permitAll()//和表單登錄相關的接口統統都直接通過
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("logout success");
                    out.flush();
                }
            })
            .permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
忽略攔截分兩步

返回閱讀

增加訪問路徑/hi

/**
 * 不用登錄就可訪問
 * @return
 */
@RequestMapping("/hi")
public String sayHi(){
    return "Hi bro!";
}

增加配置代碼

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/hi");
}

即可不用登錄訪問/hi路徑

END

本文就先說到這里,有問題歡迎留言討論


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM