Spring Security(Spring安全框架)學習筆記(三)——返回json格式數據,適用前後端分離場景

Spring Security(Spring安全框架)學習筆記(一)簡介、自定義登錄頁面、放過靜態資源
Spring Security(Spring安全框架)學習筆記(二)登錄接口,登錄參數,登錄回調,註銷登錄
Spring Security(Spring安全框架)學習筆記(三)返回json格式數據,適用前後端分離場景
Spring Security(Spring安全框架)學習筆記(四)授權操作、權限繼承

一、無狀態登錄&有狀態登錄

  1. 有狀態登錄:登錄成功,服務端存session,在服務端維護用戶登錄狀態。
  2. 無狀態登錄: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>

3、目錄結構

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章