目录:
(1)快速Demo
(2)自定义登录逻辑
(3)自定义登录页面
(4)失败跳转
(5)设置请求参数的密码和用户名
(6)自定义登录处理器
(7)自定义失败处理器
(8)认证方式
.anyRequest详解
.regexMatchers详解
.mvcMatchers详解
创建项目:
(1)快速Demo
引入依赖pom.xml:引入SpringSecurity依赖,创建项目的时候选中了依赖,这里是自动导入的
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xxxx</groupId>
<artifactId>springsecuritydemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springsecuritydemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--SpringSecurity组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--test组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建控制类LoginController:
package com.xxxx.springsecuritydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("login")
public String login(){
System.out.println("执行登录方法");
return "redirect:main.html";
}
}
创建html页面:
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input type="text" name="username"/><br>
密码:<input type="text" name="password"/><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
main.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
登录成功!!!!
</body>
</html>
运行主启动类:
package com.xxxx.springsecuritydemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringsecuritydemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritydemoApplication.class, args);
}
}
浏览器输入地址访问:
我们发现这个跟我们刚才写的login不一样:这个即是SptingSecurity 带给我们的页面,有了SpringSecurity之后,我们任何操作之前呢,都需要这个页面进行行登录,然后才能进行响应操作:用户名user是SpringSecurity默认提供的
密码:
当我们启动 的时候会有提示:
输入之后就会跳到我们自己的登录页面:
(2)自定义登录逻辑
以上只是引入了SpringSecurity依赖什么都没有进行配置账户和密码都是SpringSecurity提供的,然而在实际项目中呢数据和密码都是在数据库中查询出来的, 所以我们需要自定义的逻辑进行认证的逻辑,需要实现接口UserDetailsService、PasswordEncode
演示PasswordEncode:在测试类中:
package com.xxxx.springsecuritydemo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootTest
class SpringsecuritydemoApplicationTests {
@Test
public void contextLoads() {
PasswordEncoder pe=new BCryptPasswordEncoder();
String encode = pe.encode("123");//加密
System.out.println("加密后的密码"+encode);
//判断原密码相匹配
boolean matches = pe.matches("123", encode);
System.out.println("==============");
System.out.println(matches);
}
}
实现自定义的登录逻辑:
SpringSecurity自定义登录逻辑时,spring容器中呢必须要PasswordEncode的实例所以不能向上面测试类中无new一样了需要在配置类中添加@Bean去创建:
SecurityConfig:
package com.xxxx.springsecuritydemo.config;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig {
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
UserDetailsServiceImpl:这里不查询数据库,只是先进行模拟
package com.xxxx.springsecuritydemo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder pw;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1.查询数据库判断用户名是否存在,如果不存在就会抛出UsernameNotFoundException异常
//这里进行模拟,用户名为admin
if (!"admin".equals(username)) {
throw new UsernameNotFoundException("用户名不存在");
}
//2.//如果存在,把查询出来的密码(注册时已经经过加密) 进行解析,或者直接把密码放到构造方法
String password=pw.encode("123");
return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normall"));
}
}
启动主启动类:在浏览器输入localhost:8080/login.html:
这里使用admin 和123 就可以登录了
虽然我们写了登录逻辑,但是登录页面还是SpringSecurity是它自带的登录了页面,那么在实际项目中呢都会我们自己的登录页面。
(3)自定义登录页面
配置类继承接口,重写方法
SecurityConfig
package com.xxxx.springsecuritydemo.config;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
.successForwardUrl("/toMain");
//授权认证 相当于拦截器一样
http.authorizeRequests()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
UserDetailsServiceImpl
package com.xxxx.springsecuritydemo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder pw;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1.查询数据库判断用户名是否存在,如果不存在就会抛出UsernameNotFoundException异常
//这里进行模拟,用户名为admin
if (!"admin".equals(username)) {
throw new UsernameNotFoundException("用户名不存在");
}
//2.//如果存在,把查询出来的密码(注册时已经经过加密) 进行解析,或者直接把密码放到构造方法
String password=pw.encode("123");
return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normall"));
}
}
LoginController:
package com.xxxx.springsecuritydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
/*@RequestMapping("login")
public String login(){
System.out.println("执行登录方法");
return "redirect:main.html";
}*/
@RequestMapping("toMain")
public String login(){
System.out.println("执行登录方法");
return "redirect:main.html";
}
}
重启主启动类:SpringsecuritydemoApplication
package com.xxxx.springsecuritydemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringsecuritydemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritydemoApplication.class, args);
}
}
在访问的时候,就只显示了我们定义的登录页面:
输入:
成功跳转:
(4)失败跳转
当输入账号或密码输入错误时,SpringSecurity会做什么呢?
我们发现它还是跳转登录页面,只是在后面添加的error
正常情况下会3跳到一个失败的页面
首先在配置类中添加跳转失败页面 和设置error不需要被认证
package com.xxxx.springsecuritydemo.config;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
.successForwardUrl("/toMain")
//登录失败跳转页面,Post请求
.failureForwardUrl("/toError");
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
LoginController:
package com.xxxx.springsecuritydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
/*@RequestMapping("login")
public String login(){
System.out.println("执行登录方法");
return "redirect:main.html";
}*/
//页面登录成功跳转
@RequestMapping("toMain")
public String toMain(){
return "redirect:main.html";
}
//跳转登录失败页面
@RequestMapping("toError")
public String toError(){
return "redirect:error.html";
}
}
输入错误登录密码:
点击跳转:
(5)设置请求参数的密码和用户名
注意Login.html中表单里必须是Post请求,并且 input的name属性必须为username,password,更改后不能正常跳转,这是跟过滤器相关的,可以查看这个过滤器类
Login.html:更改input属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input type="text" name="username1"/><br>
密码:<input type="text" name="password1"/><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
如果Login.html更改了name属性,需要在配置类进行相关配置:
(6)自定义登录处理器
登录成功后的跳转页面,他必须是一个Post请求,所以我们在Controller里面写了一个跳转页面的方法,进行页面的响应跳转,但是大部分的项目都是前后端分离的,基本上不会用Controoller做页面跳转了,都是一个站外的跳转,比如:跳转到www.baidu.com ,通过sucessForwordUrl()是不能进行跳转的,那么怎么实现我们的这个需求呢?
在配置类中调用SucessHandler()
创建一个类实现AuthenticationSuccessHandler
package com.xxxx.springsecuritydemo.handle;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyAuthenticationSucessHandler implements AuthenticationSuccessHandler {
private String url;
public MyAuthenticationSucessHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//其中的一个方法获取User对象
User user = (User)authentication.getPrincipal();
System.out.println(user.getUsername());
System.out.println(user.getPassword());//null
System.out.println(user.getAuthorities());//权限
response.sendRedirect(url);
}
}
配置类:
package com.xxxx.springsecuritydemo.config;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSucessHandler;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//和Login中input的属性相对应
.usernameParameter("username1")
.passwordParameter("password1")
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
//.successForwardUrl("/toMain")
//登录成功后的处理器,不能和sucessForwardUrl共存
.successHandler(new MyAuthenticationSucessHandler("http://wwww.baidu.com"))
//登录失败跳转页面,Post请求
.failureForwardUrl("/toError");
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
(7)自定义失败处理器
自定义类:MyAuthenticationFailureHandler
package com.xxxx.springsecuritydemo.handle;
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;
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
private String url;
public MyAuthenticationFailureHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.sendRedirect(url);
}
}
配置类调用:
package com.xxxx.springsecuritydemo.config;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationFailureHandler;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSucessHandler;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//和Login中input的属性相对应
.usernameParameter("username1")
.passwordParameter("password1")
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
//.successForwardUrl("/toMain")
//登录成功后的处理器,不能和sucessForwardUrl共存
.successHandler(new MyAuthenticationSucessHandler("http://wwww.baidu.com"))
//登录失败跳转页面,Post请求
//.failureForwardUrl("/toError")
//登录失败后的处理器,不能和failureForwardUrl共存
.failureHandler(new MyAuthenticationFailureHandler("/error.html"));
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
输入错误密码:
通过以上的 处理器的设置,跳转都没有通过Contrlller进行页面跳转
(8)认证方式
.anyRequest详解
anyRequest():所有请求都必须被认证,就是访问所有的页面,首先需要进行登录验证
antMatchers().permittAll():请求不需要被认证
放行resources目录下的静态资源:
package com.xxxx.springsecuritydemo.config;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationFailureHandler;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSucessHandler;
import org.springframework.context.annotation.Bean;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//和Login中input的属性相对应
.usernameParameter("username1")
.passwordParameter("password1")
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
//.successForwardUrl("/toMain")
//登录成功后的处理器,不能和sucessForwardUrl共存
.successHandler(new MyAuthenticationSucessHandler("http://wwww.baidu.com"))
//登录失败跳转页面,Post请求
//.failureForwardUrl("/toError")
//登录失败后的处理器,不能和failureForwardUrl共存
.failureHandler(new MyAuthenticationFailureHandler("/error.html"));
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//resources目录下的静态资源
.antMatchers("/js/**","/css/**","/images/**").permitAll()
//任何目录下的png图片
//.antMatchers("/**/*.png").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
浏览器输入:
.regexMatchers详解
.regexMatchers():用正则表达式进行相应的匹配,它参数可以有一个写正则表达式,可以有两个第一个是请求方式
LoginController:添加demo
package com.xxxx.springsecuritydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginController {
@GetMapping("demo")
@ResponseBody
public String demo(){
return "demo";
}
}
第一个参数必须是get请求和控制器中的GetMapper相对应,否则会被拦截
package com.xxxx.springsecuritydemo.config;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationFailureHandler;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSucessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//和Login中input的属性相对应
.usernameParameter("username1")
.passwordParameter("password1")
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
//.successForwardUrl("/toMain")
//登录成功后的处理器,不能和sucessForwardUrl共存
.successHandler(new MyAuthenticationSucessHandler("http://wwww.baidu.com"))
//登录失败跳转页面,Post请求
//.failureForwardUrl("/toError")
//登录失败后的处理器,不能和failureForwardUrl共存
.failureHandler(new MyAuthenticationFailureHandler("/error.html"));
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//resources目录下的静态资源
.antMatchers("/static/js/**", "/static/css/**", "/static/images/**").permitAll()
//regexMatchers放行的使用
.regexMatchers(".+[.]png").permitAll()
.regexMatchers(HttpMethod.GET,"/demo").permitAll()
//任何目录下的png图片
//.antMatchers("/**/*.png").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
mvcMatchers详解
通常是设置servlet path的一种情况 ,这个servlet path并不是:
以前我们在控制类加上@RequestMapping注解,这并不是servlet path,它只是给控制类中的所有方法加了一个前缀而已,访问的时候加上demo+toMain ,它并不是整个项目,它只是这个Controller,
真正的servlet path是在sptingboot配置文件中进行配置
application.properties:
spring.mvc.servlet.path=/xxxx
然后重启项目进行访问,这样访问也会被拦截的,跳到Login.html去了,Login.html也需要加xxxx,所以需要进行配置.mvcMatchers
package com.xxxx.springsecuritydemo.config;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationFailureHandler;
import com.xxxx.springsecuritydemo.handle.MyAuthenticationSucessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//自定义登录页面,不使用自带的
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
//和Login中input的属性相对应
.usernameParameter("username1")
.passwordParameter("password1")
//当发现是 /login是认为是登录,必须和表单提交的地址一样,去执行UserDetailsServiceImpl登录逻辑
.loginProcessingUrl("/login")
//自定义登录页面
.loginPage("/login.html")
//登录成功之后跳转页面,必须是Post请求
//.successForwardUrl("/toMain")
//登录成功后的处理器,不能和sucessForwardUrl共存
.successHandler(new MyAuthenticationSucessHandler("http://wwww.baidu.com"))
//登录失败跳转页面,Post请求
//.failureForwardUrl("/toError")
//登录失败后的处理器,不能和failureForwardUrl共存
.failureHandler(new MyAuthenticationFailureHandler("/error.html"));
//授权认证 相当于拦截器一样
http.authorizeRequests()
//error.html不需要被认证
.antMatchers("/error.html").permitAll()
//login.html不需要被认证
.antMatchers("/login.html").permitAll()
//resources目录下的静态资源
.antMatchers("/static/js/**", "/static/css/**", "/static/images/**").permitAll()
//regexMatchers放行的使用
//.regexMatchers(".+[.]png").permitAll()
//.regexMatchers(HttpMethod.GET,"/demo").permitAll()
//.mvcMatchers("/demo").servletPath("/xxxx").permitAll()
//如果不习惯mvcMatchers还可以用antMatchers设置等效
.antMatchers("/xxxx/demo").permitAll()
//任何目录下的png图片
//.antMatchers("/**/*.png").permitAll()
//所有请求都必须被认证,必须登录之后能被访问
.anyRequest().authenticated();
//关闭csrf防护
http.csrf().disable();
}
//创建PasswordEncoder实例
@Bean
public PasswordEncoder getPw(){
return new BCryptPasswordEncoder();
}
}
内置访问控制方法: