security学习笔记
spring security 入门案例
- 创建springboot工程
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.创建controller
package com.example.springscuritydemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 崔令雨
* @date 2022/5/19 21:24
* @Version 1.0
*/
@RestController
@RequestMapping("test")
public class TestController {
@GetMapping("hello")
public String hello() {
return "hello security";
}
}
- 启动程序访问我们的控制器方法 会弹出下图界面 用户名是 user 密码在控制台输出
修改默认用户名密码
- 在配置文件中配置用户名密码用来覆盖默认配置
spring.security.user.name=root
spring.security.user.password=root
自定义认证资源规则
- 自定义配置类继承 WebSecurityConfigurerAdapter
package com.example.springscuritydemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin();
}
}
自定义登录页面
- 引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 创建登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="login-box">
<h2>Login</h2>
<form method="post" th:action="/login">
<div class="user-box">
<input name="username" required="" type="text">
<label>Username</label>
</div>
<div class="user-box">
<input name="password" required="" type="password">
<label>Password</label>
</div>
<a href="#">
<span></span>
<span></span>
<span></span>
<span></span>
Submit
</a>
</form>
</div>
</body>
</html>
页面所需css
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background: linear-gradient(#141e30, #243b55);
}
.login-box {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
padding: 40px;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, .5);
box-sizing: border-box;
box-shadow: 0 15px 25px rgba(0, 0, 0, .6);
border-radius: 10px;
}
.login-box h2 {
margin: 0 0 30px;
padding: 0;
color: #fff;
text-align: center;
}
.login-box .user-box {
position: relative;
}
.login-box .user-box input {
width: 100%;
padding: 10px 0;
font-size: 16px;
color: #fff;
margin-bottom: 30px;
border: none;
border-bottom: 1px solid #fff;
outline: none;
background: transparent;
}
.login-box .user-box label {
position: absolute;
top: 0;
left: 0;
padding: 10px 0;
font-size: 16px;
color: #fff;
pointer-events: none;
transition: .5s;
}
.login-box .user-box input:focus ~ label,
.login-box .user-box input:valid ~ label {
top: -20px;
left: 0;
color: #03e9f4;
font-size: 12px;
}
.login-box form a {
position: relative;
display: inline-block;
padding: 10px 20px;
color: #03e9f4;
font-size: 16px;
text-decoration: none;
text-transform: uppercase;
overflow: hidden;
transition: .5s;
margin-top: 40px;
letter-spacing: 4px
}
.login-box a:hover {
background: #03e9f4;
color: #fff;
border-radius: 5px;
box-shadow: 0 0 5px #03e9f4,
0 0 25px #03e9f4,
0 0 50px #03e9f4,
0 0 100px #03e9f4;
}
.login-box a span {
position: absolute;
display: block;
}
.login-box a span:nth-child(1) {
top: 0;
left: -100%;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, #03e9f4);
animation: btn-anim1 1s linear infinite;
}
@keyframes btn-anim1 {
0% {
left: -100%;
}
50%, 100% {
left: 100%;
}
}
.login-box a span:nth-child(2) {
top: -100%;
right: 0;
width: 2px;
height: 100%;
background: linear-gradient(180deg, transparent, #03e9f4);
animation: btn-anim2 1s linear infinite;
animation-delay: .25s
}
@keyframes btn-anim2 {
0% {
top: -100%;
}
50%, 100% {
top: 100%;
}
}
.login-box a span:nth-child(3) {
bottom: 0;
right: -100%;
width: 100%;
height: 2px;
background: linear-gradient(270deg, transparent, #03e9f4);
animation: btn-anim3 1s linear infinite;
animation-delay: .5s
}
@keyframes btn-anim3 {
0% {
right: -100%;
}
50%, 100% {
right: 100%;
}
}
.login-box a span:nth-child(4) {
bottom: -100%;
left: 0;
width: 2px;
height: 100%;
background: linear-gradient(360deg, transparent, #03e9f4);
animation: btn-anim4 1s linear infinite;
animation-delay: .75s
}
@keyframes btn-anim4 {
0% {
bottom: -100%;
}
50%, 100% {
bottom: 100%;
}
}
- 关闭thymeleaf缓存
spring.thymeleaf.cache=false
- 定义控制器
package com.example.springscuritydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 崔令雨
* @date 2022/5/21 14:48
* @Version 1.0
*/
@Controller
public class LoginController {
@RequestMapping("login.html")
public String login() {
return "login";
}
}
- 设置security配置
package com.example.springscuritydemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/login.css").permitAll()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin()
//设置登录页面
.loginPage("/login.html")
.loginProcessingUrl("/login") // 设置验证请求路径
// .successForwardUrl("/test/hello") //验证成功后请求转发到指定页面 请求转发到指定页
//验证成功后默认跳转到第一次发送请求页面
// .defaultSuccessUrl("/index/hello") // 设置默认跳转页面 请求重定向到指定页
.usernameParameter("usern") //设置用户名属性
.passwordParameter("paswd") //设置密码属性
.failureUrl("/index.html")//请求失败后跳转页面
//禁用crsf
.and().csrf().disable();
}
}
错误页面
1. 显示错误信息
1. 创建错误页面
<head>
<title>FlexBox Exercise #3 - Image carousel / Responsive </title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="carousel">
<div class="carousel__nav">
<span id="moveLeft" class="carousel__arrow">
<svg class="carousel__icon" width="24" height="24" viewBox="0 0 24 24">
<path d="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"></path>
</svg>
</span>
<span id="moveRight" class="carousel__arrow" >
<svg class="carousel__icon" width="24" height="24" viewBox="0 0 24 24">
<path d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path>
</svg>
</span>
</div>
<div class="carousel-item carousel-item--1">
<div class="carousel-item__image"></div>
<div class="carousel-item__info">
<div class="carousel-item__container">
<h2 class="carousel-item__subtitle">The grand moment </h2>
<h1 class="carousel-item__title">Le tour</h1>
<p class="carousel-item__description">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.</p>
<a href="#" class="carousel-item__btn">Explore the tour</a>
</div>
</div>
</div>
<div class="carousel-item carousel-item--2">
<div class="carousel-item__image"></div>
<div class="carousel-item__info">
<div class="carousel-item__container">
<h2 class="carousel-item__subtitle">The big window </h2>
<h1 class="carousel-item__title">Minimal window</h1>
<p class="carousel-item__description">Clear Glass Window With Brown and White Wooden Frame iste natus error sit voluptatem accusantium doloremque laudantium.</p>
<a href="#" class="carousel-item__btn">Read the article</a>
</div>
</div>
</div>
<div class="carousel-item carousel-item--3">
<div class="carousel-item__image"></div>
<div class="carousel-item__info">
<div class="carousel-item__container">
<h2 class="carousel-item__subtitle">Tropical palms </h2>
<h1 class="carousel-item__title">Palms</h1>
<p class="carousel-item__description">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.</p>
<a href="#" class="carousel-item__btn">Explore the palms</a>
</div>
</div>
</div>
<div class="carousel-item carousel-item--4">
<div class="carousel-item__image"></div>
<div class="carousel-item__info">
<div class="carousel-item__container">
<h2 class="carousel-item__subtitle">Beach </h2>
<h1 class="carousel-item__title">The beach </h1>
<p class="carousel-item__description">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.</p>
<a href="#" class="carousel-item__btn">Explore the beach</a>
</div>
</div>
</div>
<div class="carousel-item carousel-item--5">
<div class="carousel-item__image"></div>
<div class="carousel-item__info">
<div class="carousel-item__container">
<h2 class="carousel-item__subtitle">The white building </h2>
<h1 class="carousel-item__title">White building</h1>
<p class="carousel-item__description">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.</p>
<a href="#" class="carousel-item__btn">Read the article</a>
</div>
</div>
</div>
</div>
</body>
2. 错误页面相关css
@import url('https://fonts.googleapis.com/css?family=Playfair+Display:400,400i,700,700i,900,900i');
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i,800,800i');
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
}
body {
background-color: #eaeaea;
}
.carousel {
width: 100%;
height: 100%;
display: flex;
max-width: 900px;
max-height: 550px;
overflow: hidden;
position: relative;
}
.carousel-item {
visibility: visible;
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: flex-end;
-webkit-align-items: center;
-webkit-justify-content: flex-end;
position: relative;
background-color: #fff;
flex-shrink: 0;
-webkit-flex-shrink: 0;
position: absolute;
z-index: 0;
transition: 0.6s all linear;
}
.carousel-item__info {
height: 100%;
display: flex;
justify-content: center;
flex-direction: column;
display: -webkit-flex;
-webkit-justify-content: center;
-webkit-flex-direction: column;
order: 1;
left: 0;
margin: auto;
padding: 0 40px;
width: 40%;
}
.carousel-item__image {
width: 60%;
height: 100%;
order: 2;
align-self: flex-end;
flex-basis: 60%;
-webkit-order: 2;
-webkit-align-self: flex-end;
-webkit-flex-basis: 60%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: relative;
transform: translateX(100%);
transition: 0.6s all ease-in-out;
}
.carousel-item__subtitle {
font-family: 'Open Sans', sans-serif;
letter-spacing: 3px;
font-size: 10px;
text-transform: uppercase;
margin: 0;
color: #7E7E7E;
font-weight: 700;
transform: translateY(25%);
opacity: 0;
visibility: hidden;
transition: 0.4s all ease-in-out;
}
.carousel-item__title {
margin: 15px 0 0 0;
font-family: 'Playfair Display', serif;
font-size: 44px;
line-height: 45px;
letter-spacing: 3px;
font-weight: 700;
color: #2C2C2C;
transform: translateY(25%);
opacity: 0;
visibility: hidden;
transition: 0.6s all ease-in-out;
}
.carousel-item__description {
transform: translateY(25%);
opacity: 0;
visibility: hidden;
transition: 0.6s all ease-in-out;
margin-top: 35px;
font-family: 'Open Sans', sans-serif;
font-size: 13px;
color: #7e7e7e;
line-height: 22px;
margin-bottom: 35px;
}
.carousel-item--1 .carousel-item__image {
background-image: url('https://images.pexels.com/photos/991012/pexels-photo-991012.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940');
}
.carousel-item--2 .carousel-item__image {
background-image: url('https://images.pexels.com/photos/921294/pexels-photo-921294.png?auto=compress&cs=tinysrgb&h=750&w=1260');
}
.carousel-item--3 .carousel-item__image {
background-image: url('https://images.pexels.com/photos/92733/pexels-photo-92733.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260');
}
.carousel-item--4 .carousel-item__image {
background-image: url('https://images.pexels.com/photos/1008732/pexels-photo-1008732.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260');
}
.carousel-item--5 .carousel-item__image {
background-image: url('https://images.pexels.com/photos/1029614/pexels-photo-1029614.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940');
}
.carousel-item__container {
}
.carousel-item__btn {
width: 35%;
color: #2C2C2C;
font-family: 'Open Sans', sans-serif;
letter-spacing: 3px;
font-size: 11px;
text-transform: uppercase;
margin: 0;
width: 35%;
font-weight: 700;
text-decoration: none;
transform: translateY(25%);
opacity: 0;
visibility: hidden;
transition: 0.6s all ease-in-out;
}
.carousel__nav {
position: absolute;
right: 0;
z-index: 2;
background-color: #fff;
bottom: 0;
}
.carousel__icon {
display: inline-block;
vertical-align: middle;
width: 16px;
fill: #5d5d5d;
}
.carousel__arrow {
cursor: pointer;
display: inline-block;
padding: 11px 15px;
position: relative;
}
.carousel__arrow:nth-child(1):after {
content: '';
right: -3px;
position: absolute;
width: 1px;
background-color: #b0b0b0;
height: 14px;
top: 50%;
margin-top: -7px;
}
.active {
z-index: 1;
display: flex;
visibility: visible;
}
.active .carousel-item__subtitle, .active .carousel-item__title, .active .carousel-item__description, .active .carousel-item__btn {
transform: translateY(0);
opacity: 1;
transition: 0.6s all ease-in-out;
visibility: visible;
}
.active .carousel-item__image {
transition: 0.6s all ease-in-out;
transform: translateX(0);
}
.box {
width: 30px;
height: 60px;
display: table;
}
.wrap {
display: table-cell;
verical-align: middle;
}
3. 错误页面js
$(function () {
$('.carousel-item').eq(0).addClass('active');
var total = $('.carousel-item').length;
var current = 0;
$('#moveRight').on('click', function () {
var next = current;
current = current + 1;
setSlide(next, current);
});
$('#moveLeft').on('click', function () {
var prev = current;
current = current - 1;
setSlide(prev, current);
});
function setSlide(prev, next) {
var slide = current;
if (next > total - 1) {
slide = 0;
current = 0;
}
if (next < 0) {
slide = total - 1;
current = total - 1;
}
$('.carousel-item').eq(prev).removeClass('active');
$('.carousel-item').eq(slide).addClass('active');
setTimeout(function () {
}, 800);
console.log('current ' + current);
console.log('prev ' + prev);
}
});
4. 配置WebSecurityConfig
package com.example.springscuritydemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/login.css").permitAll()
.mvcMatchers("/error.html").permitAll()
.mvcMatchers("/error.css").permitAll()
.mvcMatchers("/error.js").permitAll()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin()
//设置登录页面
.loginPage("/login.html")
.loginProcessingUrl("/login") // 设置验证请求路径
// .successForwardUrl("/test/hello") //验证成功后请求转发到指定页面 请求转发到指定页
//验证成功后默认跳转到第一次发送请求页面
// .defaultSuccessUrl("/index/hello") // 设置默认跳转页面 请求重定向到指定页
.usernameParameter("usern") //设置用户名属性
.passwordParameter("paswd") //设置密码属性
// .successHandler(new MyAuthenticationSuccessHandler())// 设置返回处理器
.failureUrl("/error.html")//请求失败后跳转页面 以redirect方法跳转
// .failureForwardUrl("/error.html") // 以 forward方式跳转
//禁用crsf
.and().csrf().disable();
}
}
2. 自定义异常处理
package com.example.springscuritydemo.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author 崔令雨
* @date 2022/5/21 19:47
* @Version 1.0
*/
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
Map<String, Object> map = new HashMap<>();
map.put("Message", exception.getMessage());
response.setContentType("application/json;charset=utf-8");
String s = new ObjectMapper().writeValueAsString(map);
response.getWriter().println(s);
}
}
配置security
package com.example.springscuritydemo.config;
import com.example.springscuritydemo.handler.MyAuthenticationFailureHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/login.css").permitAll()
.mvcMatchers("/error.html").permitAll()
.mvcMatchers("/error.css").permitAll()
.mvcMatchers("/error.js").permitAll()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin()
//设置登录页面
.loginPage("/login.html")
.loginProcessingUrl("/login") // 设置验证请求路径
// .successForwardUrl("/test/hello") //验证成功后请求转发到指定页面 请求转发到指定页
//验证成功后默认跳转到第一次发送请求页面
// .defaultSuccessUrl("/index/hello") // 设置默认跳转页面 请求重定向到指定页
.usernameParameter("usern") //设置用户名属性
.passwordParameter("paswd") //设置密码属性
// .successHandler(new MyAuthenticationSuccessHandler())// 设置返回处理器
// .failureUrl("/error.html")//请求失败后跳转页面 以redirect方法跳转
// .failureForwardUrl("/error.html") // 以 forward方式跳转
.failureHandler(new MyAuthenticationFailureHandler())
//禁用crsf
.and().csrf().disable();
}
}
注销登录
- 注销之后跳转页面
package com.example.springscuritydemo.config;
import com.example.springscuritydemo.handler.MyAuthenticationFailureHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/login.css").permitAll()
.mvcMatchers("/error.html").permitAll()
.mvcMatchers("/error.css").permitAll()
.mvcMatchers("/error.js").permitAll()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin()
//设置登录页面
.loginPage("/login.html")
.loginProcessingUrl("/login") // 设置验证请求路径
// .successForwardUrl("/test/hello") //验证成功后请求转发到指定页面 请求转发到指定页
//验证成功后默认跳转到第一次发送请求页面
// .defaultSuccessUrl("/index/hello") // 设置默认跳转页面 请求重定向到指定页
.usernameParameter("usern") //设置用户名属性
.passwordParameter("paswd") //设置密码属性
// .successHandler(new MyAuthenticationSuccessHandler())// 设置返回处理器
// .failureUrl("/error.html")//请求失败后跳转页面 以redirect方法跳转
// .failureForwardUrl("/error.html") // 以 forward方式跳转
.failureHandler(new MyAuthenticationFailureHandler())
//禁用crsf
.and()
.logout()//
// .logoutUrl("/logout")// 指定注销登录的请求路径默认get方式
.logoutRequestMatcher(
new AntPathRequestMatcher("/aa", "GET") //自定义退出路径以及请求方式
)
.and().csrf().disable();
}
}
-
注销之后返回json
配置注销处理器
package com.example.springscuritydemo.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author 崔令雨
* @date 2022/5/22 9:44
* @Version 1.0
*/
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
Map<String, Object> map = new HashMap<>();
map.put("msg", authentication);
map.put("status", 200);
response.setContentType("application/json;charset=utf-8");
String s = new ObjectMapper().writeValueAsString(map);
response.getWriter().println(s);
}
}
修改security配置
package com.example.springscuritydemo.config;
import com.example.springscuritydemo.handler.MyAuthenticationFailureHandler;
import com.example.springscuritydemo.handler.MyLogoutSuccessHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
/**
* @author 崔令雨
* @date 2022/5/21 13:44
* @Version 1.0
*/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/login.html").permitAll()
.mvcMatchers("/login.css").permitAll()
.mvcMatchers("/error.html").permitAll()
.mvcMatchers("/error.css").permitAll()
.mvcMatchers("/error.js").permitAll()
//匹配请求路径 并放行 /index/hello 最左边的斜杠必须加 不然失效
.mvcMatchers("/index/hello").permitAll()
// 所有请求 认证后放行
.anyRequest().authenticated()
//认证方式表单认证
.and().formLogin()
//设置登录页面
.loginPage("/login.html")
.loginProcessingUrl("/login") // 设置验证请求路径
// .successForwardUrl("/test/hello") //验证成功后请求转发到指定页面 请求转发到指定页
//验证成功后默认跳转到第一次发送请求页面
// .defaultSuccessUrl("/index/hello") // 设置默认跳转页面 请求重定向到指定页
.usernameParameter("usern") //设置用户名属性
.passwordParameter("paswd") //设置密码属性
// .successHandler(new MyAuthenticationSuccessHandler())// 设置返回处理器
// .failureUrl("/error.html")//请求失败后跳转页面 以redirect方法跳转
// .failureForwardUrl("/error.html") // 以 forward方式跳转
.failureHandler(new MyAuthenticationFailureHandler())
//禁用crsf
.and()
.logout()//
// .logoutUrl("/logout")// 指定注销登录的请求路径默认get方式
.logoutRequestMatcher(
new AntPathRequestMatcher("/aa", "GET") //自定义退出路径以及请求方式
)
.logoutSuccessHandler(new MyLogoutSuccessHandler())
.and().csrf().disable();
}
}
获取用户数据
- 单线程获取用户数据
package com.example.springscuritydemo.controller;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 崔令雨
* @date 2022/5/21 13:42
* @Version 1.0
*/
@RestController
@RequestMapping("index")
public class IndexController {
@RequestMapping("hello")
public String hello() {
return "index hello";
}
@RequestMapping("user")
public String user() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
System.out.println("authentication.getPrincipal() = " + authentication.getPrincipal());
System.out.println("authentication.getAuthorities() = " + authentication.getAuthorities());
return "hello user";
}
}
- 多线程模式下获取用户数据
需要对vm options 参数修改 之后在运行过程中 主线程会将用户信息复制一份放到子线程中
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
- 在页面获取用户信息
- 引入依赖
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
在页面添加命名空间
<html lang="en" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
获取用户信息
<!--获取认证用户名-->
<ul>
<li sec:authentication="principal.username"></li>
<li sec:authentication="principal.authorities"></li>
<li sec:authentication="principal.accountNonExpired"></li>
<li sec:authentication="principal.accountNonLocked"></li>
<li sec:authentication="principal.credentialsNonExpired"></li>
</ul>
作者:01cui
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.