使用SpringSecurity
前幾天寫了一個SpringBoot對攔截器的使用,在實際項目中,對一些情況需要做一些安全驗證,比如在沒有登錄的情況下訪問特定的頁面應該解釋的攔截處理。這一篇介紹使用SpringSecurity來做簡單的安全控制,由於SpringSecurity比較復雜,如果有不對的地方可以大家一起學習。
新建項目,前端頁面使用thymeleaf,加入security依賴,pom文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dalaoyang</groupId> <artifactId>springboot_security</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot_security</name> <description>springboot_security</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </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-security</artifactId> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.15</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
配置文件本文就是將之前整合thymeleaf的配置拿了過來,代碼如下:
##端口號 server.port=8888 ##去除thymeleaf的html嚴格校驗 spring.thymeleaf.mode=LEGACYHTML5 #設定thymeleaf文件路徑 默認為src/main/resources/templates spring.freemarker.template-loader-path=classpath:/templates #設定靜態文件路徑,js,css等 spring.mvc.static-path-pattern=/static/** # 是否開啟模板緩存,默認true # 建議在開發時關閉緩存,不然沒法看到實時頁面 spring.thymeleaf.cache=false # 模板編碼 spring.freemarker.charset=UTF-8
接下來是這篇文章重要的地方,新建一個SecurityConfig類,繼承WebSecurityConfigurerAdapter類,重寫configure(HttpSecurity httpSecurity)方法,其中/css/和/index的資源不需要驗證,直接可以請求,/user/的資源需要驗證,權限是USER,/admin/**的資源需要驗證,權限是ADMIN,登錄地址是/login,登錄失敗地址是/login_error,異常重定向到 /401,註銷跳轉到/logout。
註入AuthenticationManagerBuilder,在內存中創建一個用戶dalaoyang,密碼123的用戶,權限是USER,代碼如下:
package com.dalaoyang.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
/**
* @author dalaoyang
* @Description
* @project springboot_learn
* @package com.dalaoyang.config
* @email [email protected]
* @date 2018/4/28
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// /css/**和/index的資源不需要驗證,直接可以請求
// /user/**的資源需要驗證,權限是USER /admin/**的資源需要驗證,權限是ADMIN
// 登錄地址是/login 登錄失敗地址是 /login_error
// 異常重定向到 /401
// 註銷跳轉到 /logout
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity
.authorizeRequests()
.antMatchers("/css/**","/index").permitAll()
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.and()
.formLogin().loginPage("/login").failureUrl("/login_error")
.and()
.exceptionHandling().accessDeniedPage("/401");
httpSecurity.logout().logoutSuccessUrl("/logout");
}
//內存中創建用戶,用戶名為dalaoyang,密碼123,權限是USER
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("dalaoyang").password("123").roles("USER");
}
}
創建一個TestController負責跳轉,代碼如下:
package com.dalaoyang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author dalaoyang
* @Description
* @project springboot_learn
* @package com.dalaoyang.controller
* @email [email protected]
* @date 2018/4/28
*/
@Controller
public class TestController {
@RequestMapping("/")
public String index(){
return "index";
}
@RequestMapping("/index")
public String index2(){
return "index";
}
@RequestMapping("/user")
public String user(){
return "user/index";
}
@RequestMapping("/admin")
public String admin(){
return "admin/index";
}
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/login_error")
public String login_error(Model model){
model.addAttribute("login_error", "用戶名或密碼錯誤");
return "login";
}
@RequestMapping("/logout")
public String logout(Model model){
model.addAttribute("login_error", "註銷成功");
return "login";
}
@RequestMapping("/401")
public String error(){
return "401";
}
}
創建一個user/index.html,用於校驗USER權限,沒有登錄的話不能直接訪問,代碼如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>user/index</title>
</head>
<body>
user/index
<form th:action="@{/logout}" method="post">
<input type="submit" value="註銷"/>
</form>
</body>
</html>
創建一個admin/index.html,只允許ADMIN權限訪問,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>admin</title>
</head>
<body>
admin/index
</body>
</html>
401頁面,用於沒有權限跳轉:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>401</title>
</head>
<body>
401
</body>
</html>
index頁面,任何權限都能訪問
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
index
</body>
</html>
login頁面,用於登錄
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<h1>login</h1>
<form th:action="@{/login}" method="post">
<span th:text="${login_error}"></span>
<br/>
<input type="text" name="username">用戶名<br/>
<input type="password" name="password">密碼<br/>
<input type="submit" value="登錄">
</form>
</body>
</html>
到這裏就全部創建完成了,啟動項目,訪問http://localhost:8888/,如圖,可以直接訪問。
訪問http://localhost:8888/user被攔截到http://localhost:8888/login,如圖
先輸入錯誤的密碼,如圖
然後輸入用戶名dalaoyang密碼123,點擊登錄結果如圖
訪問http://localhost:8888/admin,如圖,沒有權限
我們在回到http://localhost:8888/user點擊註銷,如圖
源碼下載 :大老楊碼雲
個人網站:https://dalaoyang.cn
使用SpringSecurity