Spring Security(Spring安全框架)學習筆記(一)簡介、自定義登錄頁面、放過靜態資源
Spring Security(Spring安全框架)學習筆記(二)登錄接口,登錄參數,登錄回調,註銷登錄
Spring Security(Spring安全框架)學習筆記(三)返回json格式數據,適用前後端分離場景
Spring Security(Spring安全框架)學習筆記(四)授權操作、權限繼承
一、無狀態登錄&有狀態登錄
- 有狀態登錄:登錄成功,服務端存session,在服務端維護用戶登錄狀態。
- 無狀態登錄:JSON Web Token(JWT)
jwt簡介:是目前最流行的跨域身份驗證解決方案。
二、代碼
1、SecurityConfig.java
package com.hx.security;
import com.fasterxml.jackson.databind.ObjectMapper;
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.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.io.PrintWriter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
// 密碼加密實例
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // 採用不加密方式
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置用戶名,密碼
//這裏的配置會覆蓋properties配置文件中配置的賬號密碼
// 配置多個使用and連接,一個就不用加and()
auth.inMemoryAuthentication()
.withUser("whx")
.password("a")
.roles("admin")
.and()
.withUser("hx")
.password("a")
.roles("user");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**", "images/**"); //放過靜態資源下的js,css,img資源
}
@Override
protected void configure(HttpSecurity http) throws Exception { //http安全配置
//authorizeRequests開啓配置
http.authorizeRequests()
.anyRequest() //anyRequest所有請求都攔截
.authenticated()
.and()
.formLogin() //formLogin表單配置
.loginPage("/login.html") //loginPage指定登錄頁面(登錄接口)
.loginProcessingUrl("/doLogin") //指定登錄請求接口,若不配置則與指定的loginPage相同
.usernameParameter("uname") //指定請求用戶名的name屬性
.passwordParameter("pwd") //指定請求密碼的name屬性
//登錄成功的回調
.successHandler((req,resp,authentication) -> { //authentication:存儲用戶信息
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將用戶信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString(authentication.getPrincipal()));
out.flush();
out.close();
})
//登錄失敗的回調
.failureHandler((req,resp,exception) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString(exception.getMessage()));
out.flush();
out.close();
})
.permitAll()
.and()
.logout()
.logoutUrl("/logout") //配置退出登錄地址
.logoutSuccessHandler((req,resp,authentication) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString("loginout success"));
out.flush();
out.close();
})
.and()
.csrf().disable() //關閉csrf
.exceptionHandling()
.authenticationEntryPoint((req,resp,e) -> {
resp.setContentType("application/json;charset=utf-8");
resp.setStatus(401); //設置響應狀態碼,401
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString("unlogin"));
out.flush();
out.close();
});
}
}
2、login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/doLogin" method="post"> <!-- 必須指定爲post請求,地址爲login.html -->
用戶名:<input name="uname"> <br> <!-- 指定名稱username,遵循規範 -->
密碼:<input name="pwd"> <br> <!-- 指定名稱password,遵循規範 -->
<button type="submit">提交</button>
</form>
</body>
</html>