Spring Boot2.0使用Spring Security


 一、Spring Secutity簡介

    Spring 是一個非常流行和成功的 Java 應用開發框架。Spring Security 基於 Spring 框架,提供了一套 Web 應用安全性的完整解決方案。一般來說,Web 應用的安全性包括用戶認證(Authentication)和用戶授權(Authorization)兩個部分。用戶認證指的是驗證某個用戶是否為系統中的合法主體,也就是說用戶能否訪問該系統。用戶認證一般要求用戶提供用戶名和密碼。系統通過校驗用戶名和密碼來完成認證過程。用戶授權指的是驗證某個用戶是否有權限執行某個操作。在一個系統中,不同用戶所具有的權限是不同的。比如對一個文件來說,有的用戶只能進行讀取,而有的用戶可以進行修改。一般來說,系統會為不同的用戶分配不同的角色,而每個角色則對應一系列的權限。

    對於上面提到的兩種應用情景,Spring Security 框架都有很好的支持。在用戶認證方面,Spring Security 框架支持主流的認證方式,包括 HTTP 基本認證、HTTP 表單驗證、HTTP 摘要認證、OpenID 和 LDAP 等。在用戶授權方面,Spring Security 提供了基於角色的訪問控制和訪問控制列表(Access Control List,ACL),可以對應用中的領域對象進行細粒度的控制。

   另外Spring Security也集成了OAuth2.0,接下來我們就介紹下這兩種使用的,當然Spring Security還集成CAS等等,如果你要了解更多請查看官方文檔,我們下面的都是使用Spring Boot2.0做的demo,2.0以后已經集成了Spring Security5.0以上的版本;

 二、Basic認證

   這個也是我們經常使用的基於表單的認證,輸入一個賬號和密碼點擊登錄這種,就是Basic認證,我們接下主要會講一下使用以及5.0以后做了那些升級;

   1.使用以及常用的一些參數的介紹

   第一步使用Maven引入Spring Security jia包,這里我們使用Thymeleaf作為前端模板頁面,這里也有一個地方可以探討一波,為什么Spring MVC可以自由切換模板,這個地方我們找個機會一起探討,這里先做下簡單的介紹;

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- 前端模板 thymeleaf 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--安全認證框架-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>
View Code

  第二步引入Java配置配置方案

  這里我們先使用@Configuration和@EnableWebSecurity對Java類進行配置,不懂這是什么原因的可以參考下我這篇文章,接下來我們就是繼承WebSecurityConfigurerAdapter,對里面的方法重寫就可以了,分別是對AuthenticationManagerBuilder,WebSecurity,HttpSecurity方法,我們主要介紹AuthenticationManagerBuilder和HttpSecurity,通過對這兩種方法重寫最終實現我們自定義認證;

  先來介紹一下HttpSecurity常用參數,如下圖用法基本脫離不了下面這些方法,可以基於認證的方式有formLogin、openidLogin、oauth2Login,還可以做一些記住賬號操作rememberMe,還可以進行session配置管理,還支持登出loginout等等,使用起來還是蠻簡單的,大家可以參照一下這篇文章,還是蠻詳細的;

  接下來我們再看下AuthenticationManagerBuilder,我們重寫這個方法,可以基於內存用戶認證、數據庫認證、LDAP認證、還可以自定義用戶服務、還可以自己定義認證。這里我們使用自定義認證的做demo,另外這個大家還可能有一個困惑的點,configGlobal和configure的差別在哪里,這里大家可以參考下這篇文章,Spring Security從3.2版本以后就默認開啟了CRSF防護,這里是通過Token方式去檢測的,在登陸的時候Thymeleaf模板會生成_csrf的標簽來防止CRSF,對CSRF不懂的大家可以看下這篇文章,這個里面介紹一些防護CSRF的手段,大家可以思考下,我的demo只是一個簡單的架子,為了是給大家介紹一些知識,可擴展大家根據這些介紹的知識可以隨心所欲的擴展自己想要的,不要拘泥於一種方法;

 最后我還要介紹一下加密的方式,Spring Security 4的時候我們常用的加密方式是MD5加鹽的方式,5.0以后版本就找不到Md5PasswordEncoder,說明這個方法還是不夠安全,還是可以通過暴力破解可以搞定,可能我不行但是攔不住一些高手,大家可以看下官方支持的以及棄用一些方法:

  使用我就不介紹了,有興趣可以自己探索一波,還可以參考一下文章一文章二,下面我粘貼我的代碼,講到的這些可以擴展的地方大家我在代碼中會標識清楚,喜歡動手可以嘗試一下,我的重點是OAuth2驗證;

/**
 *自定義認證
 * Created by wangt on 2018/7/29.
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * http資源認證
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/","/home").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }

    /**
     * 自定義認證策略
     */
    @Autowired
    public void configGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider()).eraseCredentials(true);
    }

    @Bean
    public AuthProvider authProvider(){
        return new AuthProvider();
    }
}


/**
 * 自定義認證
 * Created by wangt on 2018/8/18.
 */
public class AuthProvider implements AuthenticationProvider {
    private final BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userName = authentication.getName();
        String inputPassword = (String) authentication.getCredentials();

        //如果你要使用thymeleaf認證方言可以擴展一下User
        //GrantedAuthority這個是使用方言的屬性,有興趣了解下
        //其實也就是通過這個使用if去判斷
        User user =new User();
        user.setName("admin");
        user.setPassword("admin");
        if (user == null) {
            throw new AuthenticationCredentialsNotFoundException("authError");
        }

        //這一塊可以自定義一些加密方式
        //自己動手實現一下
        if (true) {
            //這塊有好幾個構造
            //如果使用方言你可以使用3個參數的構造函數
            return new UsernamePasswordAuthenticationToken(user, null);

        }

        throw new BadCredentialsException("authError");
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}


/**
 * Created by wangt on 2018/8/18.
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    //如果使用thymeleaf方言在這塊擴展
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/hello").setViewName("hello");
        registry.addViewController("/login").setViewName("login");
    }
}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--主頁面 index-->
您好!歡迎光臨!
<a href="/login">登錄</a>
<a href="/hello">限制訪問的頁面</a>
</body>
</html>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--hello頁面-->
hello
</body>
</html>

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--登錄頁面-->
<form th:action="@{/login}" method="post">
    <div><label> User Name : <input type="text" name="username"/> </label></div>
    <div><label> Password: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="登錄"/></div>
</form>

</body>
</html>

/**
 * 登錄控制器
 * Created by wangt on 2018/8/18.
 */
@Controller
public class LoginController {

    @GetMapping("/login")
    public String login(){
        return "/login";
    }

}

/**
 * 主頁
 * Created by wangt on 2018/7/28.
 */
@Controller
public class HomeController {

    @GetMapping("/")
    public String index(){
          return "index";
    }
}

/**
 * hello頁
 * Created by wangt on 2018/8/19.
 */
@Controller
public class HelloController {

    @GetMapping("/hello")
    public String index(){
        return "hello";
    }
}
View Code

三、下一篇再談

 OAuth2.0認證的demo我還有部分沒寫好,等等完善以后我們上傳Github,到時候在發布下篇文章,歡迎大家繼續關注!歡迎大家加我群438836709,關注微信公眾號:

  

 另外給大家道個歉,最近確實公司離職人比較多,我這邊接收的項目原來越多,還需要學習一些知識,博客更新有點緩慢,另外最近我也要轉正了,要好好整理一波,在談談人生去,希望大家體諒一下;

 

 


免責聲明!

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



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