eub:SpringSecurity的使用(二)


目录:

(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();
    }
}

内置访问控制方法:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵俺第一专栏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值