Spring Cloud 之Spring-Security

對於Spring-Security首先要明白這麼幾點:css

一、什麼是SpringSecurityurity
二、SpringSecurity應用場景
三、SpringBoot整合Security
四、Security formLogin 模式
五、Security httpBasic模式
六、Security 實現帳號權限控制
七、Security 自定義登錄界面
八、RBAC權限控制模型
http://pig.pigx.top/#/admin/rolehtml

 

什麼是SpringSecurityu
Spring Security是一個可以爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組能夠在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減小了爲企業系統安全控制編寫大量重複代碼的工做。
參考百度百科:https://baike.baidu.com/item/spring%20security/8831652?fr=aladdinjava

SpringSecurity官網:https://spring.io/projects/spring-security
Spring整合SpringSecurityu
SpringBoot整合SpringSecurityuweb

 

微服務安全框架 SpringBootSecurity
Security應用場景spring

Security在不少企業中做爲後臺角色權限框架、受權認證oauth2.0 、安全防禦(防止跨站點請求)、Session攻擊、很是容易融合SpringMVC使用等數據庫

有兩個帳戶
admin 帳戶 全部請求都有權限訪問
userAdd帳戶 只能訪問查詢和添加訂單權限
403 權限不足
401 沒有受權編程

 

環境搭建:瀏覽器

  admin帳戶  全部請求都有權限訪問緩存

  userAdd帳戶  只能訪問查詢和添加訂單tomcat

  

  關於 formLogin模式   :  表單提交認證模式 

           httpBasic模式   :瀏覽器與服務器作認證受權

 

  maven的依賴主要:

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

 

關於HttpBasic模式:

  

HTTP協議進行通訊的過程當中,HTTP協議定義了基本認證過程以容許HTTP服務器對WEB瀏覽器進行用戶身份證的方法,當一個客戶端向HTTP服務 器進行數據請求時,若是客戶端未被認證,則HTTP服務器將經過基本認證過程對客戶端的用戶名及密碼進行驗證,以決定用戶是否合法。客戶端在接收到HTTP服務器的身份認證要求後,會提示用戶輸入用戶名及密碼,而後將用戶名及密碼以BASE64加密,加密後的密文將附加於請求信息中, 如當用戶名爲toov5,密碼爲:123456時,客戶端將用戶名和密碼用「:」合併,並將合併後的字符串用BASE64加密爲密文,並於每次請求數據 時,將密文附加於請求頭(Request Header)中。HTTP服務器在每次收到請求包後,根據協議取得客戶端附加的用戶信息(BASE64加密的用戶名和密碼),解開請求包,對用戶名及密碼進行驗證,若是用 戶名及密碼正確,則根據客戶端請求,返回客戶端所須要的數據;不然,返回錯誤代碼或從新要求客戶端提供用戶名及密碼。

 

maven:

 

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依賴 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- SpringBoot整合Web組件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

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


    </dependencies>
    <!-- 注意: 這裏必需要添加, 否者各類依賴有問題 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

Controller:

 

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class OrderController {
    // 首頁
    @RequestMapping("/")
    public String index() {
        return "index";
    }

    // 查詢訂單
    @RequestMapping("/showOrder")
    public String showOrder() {
        return "showOrder";
    }

    // 添加訂單
    @RequestMapping("/addOrder")
    public String addOrder() {
        return "addOrder";
    }

    // 修改訂單
    @RequestMapping("/updateOrder")
    public String updateOrder() {
        return "updateOrder";
    }

    // 刪除訂單
    @RequestMapping("/deleteOrder")
    public String deleteOrder() {
        return "deleteOrder";
    }

    // 自定義登錄頁面
    @GetMapping("/login")
    public String login() {
        return "login";
    }

}

對於403狀態碼的錯誤處理:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ErrorController {

    // 403權限不足頁面
    @RequestMapping("/error/403")
    public String error() {
        return "/error/403";
    }

}

 

config:

 權限的配置:  

 對於fromLogin登陸頁面的修改自定義  關閉csdrf 配置loginpage就OK了

   

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

import com.mayikt.handler.MyAuthenticationFailureHandler;
import com.mayikt.handler.MyAuthenticationSuccessHandler;

// Security 配置
@Component
@EnableWebSecurity                  //繼承這個類
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired
  private MyAuthenticationFailureHandler failureHandler;
  @Autowired
  private MyAuthenticationSuccessHandler successHandler;
    // 配置認證用戶信息和權限
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 添加admin帳號
        auth.inMemoryAuthentication().withUser("admin").password("123456").
        authorities("showOrder","addOrder","updateOrder","deleteOrder");
        // 添加userAdd帳號
        auth.inMemoryAuthentication().withUser("userAdd").password("123456").authorities("showOrder","addOrder");
        // 若是想實現動態帳號與數據庫關聯 在該地方改成查詢數據庫
 
    }

    // 配置攔截請求資源
    protected void configure(HttpSecurity http) throws Exception {
        // 如何權限控制 給每個請求路徑 分配一個權限名稱 讓後帳號只要關聯該名稱,就能夠有訪問權限
        http.authorizeRequests()
        // 配置查詢訂單權限
        .antMatchers("/showOrder").hasAnyAuthority("showOrder")
        .antMatchers("/addOrder").hasAnyAuthority("addOrder")
        .antMatchers("/login").permitAll() //登陸請求不能夠攔截!
        .antMatchers("/updateOrder").hasAnyAuthority("updateOrder")
        .antMatchers("/deleteOrder").hasAnyAuthority("deleteOrder")
        .antMatchers("/**").fullyAuthenticated().and().formLogin().loginPage("/login").  //配置登陸頁面!!
        successHandler(successHandler).failureHandler(failureHandler)   //成功和失敗的配置
        .and().csrf().disable();   //csrf跨站點攻擊關閉 不然必需要傳遞token!!      
    }

    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }

}

  權限相關頁面配置:自定義web服務器參數

  

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

@Configuration
public class WebServerAutoConfiguration {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
        ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
        ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
        ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
        ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
        ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
        factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
        return factory;
    }
}

 

AuthenticationFailureHandler 認證失敗接口

AuthenticationSuccessHandler 認證成功接口

 成功和失敗的處理:

 失敗:

  

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

//認證失敗
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth)
            throws IOException, ServletException {
        System.out.println("登錄失敗!");
        res.sendRedirect("http://baidu.com");

    }

}

成功:

 

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

// 認證成功
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication arg2)
            throws IOException, ServletException {
        System.out.println("用戶認證成功");
        res.sendRedirect("/");
    }

}

啓動類:

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

@SpringBootApplication
public class AppSecurity {

    public static void main(String[] args) {
        SpringApplication.run(AppSecurity.class, args);
        // Security 兩種模式 fromLogin 表單提交認證模式 httpBasic 瀏覽器與服務器作認證受權
    }

}

yml:

# 配置freemarker
spring:
  freemarker:
    # 設置模板後綴名
    suffix: .ftl
    # 設置文檔類型
    content-type: text/html
    # 設置頁面編碼格式
    charset: UTF-8
    # 設置頁面緩存
    cache: false
    # 設置ftl文件路徑
    template-loader-path:
      - classpath:/templates
  # 設置靜態文件路徑,js,css等
  mvc:
    static-path-pattern: /static/**

 

頁面:

 

login.ftl:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

    <h1>Toov5--權限控制登錄系統</h1>
    <form action="/login" method="post">
        <span>用戶名稱</span><input type="text" name="username" /> <br>
        <span>用戶密碼</span><input type="password" name="password" /> <br>
        <input type="submit" value="登錄"> 
    </form>    
<#if RequestParameters['error']??>
用戶名稱或者密碼錯誤
</#if>
</body>
</html>
相關文章
相關標籤/搜索