# success-yeb **Repository Path**: guancg/success-yeb ## Basic Information - **Project Name**: success-yeb - **Description**: 架构前后端分离springboot+vue,涉及到的技术点 基于mysql8.x,mybatisplus3.x,springboot2.5.0,security,jwt,redis,rabbitMQ,websocket的前后端分离项目后台系统.供学习参考.如果需要数据库文件,请加849962874[QQ] - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 0 - **Created**: 2021-05-26 - **Last Updated**: 2022-03-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Mybatis-plus逆向工程 > 官网指南 - https://baomidou.com/guide/ > > 逆向工程 - yeb-generator模块中 ## 依赖 ~~~xml 4.0.0 tech.aistar yeb-demo 0.0.1-SNAPSHOT tech.aistar yeb-generator 0.0.1-SNAPSHOT yeb-generator Demo project for Spring Boot 1.8 org.freemarker freemarker com.baomidou mybatis-plus-boot-starter 3.4.3 mysql mysql-connector-java runtime com.baomidou mybatis-plus-generator 3.4.1 io.springfox springfox-boot-starter 3.0.0 org.projectlombok lombok true com.github.xiaoymin swagger-bootstrap-ui 1.9.6 org.springframework.boot spring-boot-maven-plugin ~~~ ## 配置类 > 完成之后执行main方法即可 ~~~java package tech.aistar.generator; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class CodeGenerator { /** *

* 读取控制台内容 *

*/ public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotBlank(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); gc.setOutputDir(projectPath + "/yeb-generator/src/main/java"); gc.setAuthor("亲爱的小管"); // 打开输出目录 gc.setOpen(false); // xml开启BaseResultMap gc.setBaseResultMap(true); // xml开启BaseColumnList gc.setBaseColumnList(true); //实体属性 Swagger2 注解 gc.setSwagger2(true); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/yeb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("root"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); // pc.setModuleName(scanner("模块名")); pc.setParent("tech.aistar") .setEntity("pojo") .setMapper("mapper") .setService("service") .setServiceImpl("service.impl") .setController("controller"); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return projectPath + "/yeb-generator/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录,自定义目录用"); if (fileType == FileType.MAPPER) { // 已经生成 mapper 文件判断存在,不想重新生成返回 false return !new File(filePath).exists(); } // 允许生成模板文件 return true; } }); */ cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); // 数据库表映射到实体的命名策略 strategy.setNaming(NamingStrategy.underline_to_camel); // 数据库表字段映射到实体的命名策略 strategy.setColumnNaming(NamingStrategy.no_change); // strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!"); // lombok strategy.setEntityLombokModel(true); // 生产restController strategy.setRestControllerStyle(true); // 公共父类 // strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!"); // 写于父类中的公共字段 // strategy.setSuperEntityColumns("id"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix("t_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } } ~~~ # SpringSecurity简介 > Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。 ## 快速入门 > 1. 添加依赖 > > ~~~xml > > org.springframework.boot > spring-boot-starter-security > > ~~~ > > 2. 在src/main/resources/static目录下创建Login.html文件 > > 3. 随便在哪个控制器中编写,比如 > > ~~~java > @Controller > @RequestMapping("/admin") > public class AdminController { > > @GetMapping > public String login(){ > return "login.html"; > } > } > ~~~ > > 4. 观察控制台,会发生有一段密码 > > ~~~cmd > Using generated security password: 1d212a99-7c2f-4ec0-9095-19d74168f8ff > ~~~ > > 5. 此时启动项目工程:localhost:8081/admin,会弹出Spring-security默认的登录界面,用户名为user,密码为控制台生成的[上面] > > 6. 输入验证完毕之后,可以成功跳转到login.html ## Spring Security身份认证之UserDetailsService > 之前我们采用了配置文件的方式从数据库中读取用户进行登录。虽然该方式的灵活性相较于静态账号密码的方式灵活了许多,但是将数据库的结构暴露在明显的位置上,绝对不是一个明智的做法。本文通过Java代码实现UserDetailsService接口来实现身份认证。 > ~~~java > public interface UserDetailsService { > UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; > } > ~~~ > > ~~~java > public interface UserDetails extends Serializable { > //权限信息 > Collection getAuthorities(); > //密码 > String getPassword(); > //用户名 > String getUsername(); > //账户是否过期 true : 没有 false : 过期 > boolean isAccountNonExpired(); > //账户是否锁定<是否冻结> false : 冻结 > boolean isAccountNonLocked(); > //密码是否过期 true : 没有 false : 过期 > boolean isCredentialsNonExpired(); > //账户是否可用<用户是否删除> > boolean isEnabled(); > } > ~~~ ## 权限认证模拟操作 > 1. 编写Security配置类: > > ~~~java > package tech.aistar.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; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > public class SecurityConfig { > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > ~~~ > > 2. 编写认证逻辑 > > ~~~java > package tech.aistar.service.impl2; > > 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.bcrypt.BCryptPasswordEncoder; > import org.springframework.stereotype.Service; > > /** > * 本类用来演示: 自定义登录逻辑 > * > * @author: success > * @date: 2021/5/26 7:33 下午 > */ > @Service > public class UserDetailsServiceImpl implements UserDetailsService { > > @Autowired > private BCryptPasswordEncoder bCryptPasswordEncoder; > > /** > * > * @param username 必须要和登录表单控件的name属性值保持一致,都是username > * @return > * @throws UsernameNotFoundException > */ > @Override > public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { > //1、通过提供的用户名参数访问数据库,查询记录返回过来,如果记录不存在则抛出异常 > if(!"admin".equals(username)){ > throw new UsernameNotFoundException("用户名不存在!"); > } > //2. 查询出来的凭证是被加密了的,这里是模拟查询的密码 > String password = bCryptPasswordEncoder.encode("123"); > > //3.权限不可以为空,所以需要这么一个工具方法简单实现 > return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal")); > } > } > ~~~ > > 3. 重启项目,localhost:8081/admin > > ~~~java > 重启项目,登陆测试: > > 用户名称是admin,密码是123 > > 填写的不是admin也一样报这个错误,但是控制台并没有抛出我们设置的异常(throw new UsernameNotFoundException("用户名不存在!");) > > 也就是说,UserDetails对象交给其他Security的方法来判断了 > ~~~ ## 自定义登录界面 > 1. 自定义登录界面 > > ~~~html > > > > > Title > > > >

custom login page

> >
>

username:

>

password:

>

>
> > > ~~~ > > `注意此处的name="ussername"的属性值username一定要和 loadUserByUsername(String username)方法的参数username保持一致,否则接受不到` > > 2. 在之前的Security配置类中增加这些配置: > > ~~~java > package tech.aistar.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; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > public class SecurityConfig extends WebSecurityConfigurerAdapter{ > /** > * 注意授权的请求处理,匹配的URL是重定向的地址,而不是控制器的URL。 > * @param http > * @throws Exception > */ > @Override > protected void configure(HttpSecurity http) throws Exception { > //设置登录行为为表单登录 > http.formLogin() > .loginPage("/login.html") > //此处的/login需要和表单的action的属性值保持一致 > .loginProcessingUrl("/login") > //Security的失败页面跳转也是由配置Bean的方法决定的,请求方式是POST请求 > //所以这个登陆失败的页面跳转也需要一个控制器处理 > //登录成功跳转,post请求 > .successForwardUrl("/admin/main") > //登录失败跳转,post请求 > .failureForwardUrl("/admin/error"); > > //授权认证 > http.authorizeRequests() > //设置登录页面允许访问 > .antMatchers("/login.html","/error.html").permitAll() > > //设置所有请求都要被认证 > .anyRequest().authenticated(); > > // CSRF攻击拦截关闭 > http.csrf().disable(); > } > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > ~~~ > > 3. 修改控制器 > > ~~~java > package tech.aistar.controller; > > > import org.springframework.stereotype.Controller; > import org.springframework.web.bind.annotation.GetMapping; > import org.springframework.web.bind.annotation.PostMapping; > import org.springframework.web.bind.annotation.RequestMapping; > import org.springframework.web.bind.annotation.RestController; > > /** > *

> * 前端控制器 > *

> * > * @author 亲爱的小管 > * @since 2021-05-26 > */ > @Controller > @RequestMapping("/admin") > public class AdminController { > > @GetMapping > public String login(){ > return "login.html"; > } > > /** > * 登录成功之后的跳转 > * @return > */ > @PostMapping("/main") > public String main(){ > System.out.println("main..."); > //此处只能重定向 > return "redirect:main.html"; > } > > @PostMapping("/error") > public String error(){ > System.out.println("error..."); > return "redirect:error.html"; > } > } > ~~~ > > 4. 在static目录下创建main.html和error.html - 内容随意,一个代表登录成功,一个代表登录失败 ## 自定义请求账户和密码的别名 > 之前说过login的form表单提交必须是post请求,用户名必须是username,密码必须是password,为什么呢?原因是因为这个过滤器类: > > `org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter` > > ~~~java > 代码片段: > public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username"; > public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password"; > > if (this.postOnly && !request.getMethod().equals("POST")) { > throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); > } > ~~~ > 如果要改变默认的请求参数,可以设置: > > 修改logjn.html > > ~~~html >

username:

>

password:

> ~~~ > > 修改SecurityConfig,加入俩段配置 > > `usernameParameter("uname")`和`.passwordParameter("pwd")` > > ~~~java > package tech.aistar.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; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > public class SecurityConfig extends WebSecurityConfigurerAdapter{ > /** > * 注意授权的请求处理,匹配的URL是重定向的地址,而不是控制器的URL。 > * @param http > * @throws Exception > */ > @Override > protected void configure(HttpSecurity http) throws Exception { > //设置登录行为为表单登录 > http.formLogin() > //自定义登录表单的用户名和密码的属性值 > .usernameParameter("uname") > .passwordParameter("pwd") > .loginPage("/login.html") > //此处的/login需要和表单的action的属性值保持一致 > .loginProcessingUrl("/login") > //Security的失败页面跳转也是由配置Bean的方法决定的,请求方式是POST请求 > //所以这个登陆失败的页面跳转也需要一个控制器处理 > //登录成功跳转,post请求 > .successForwardUrl("/admin/main") > //登录失败跳转,post请求 > .failureForwardUrl("/admin/error"); > > //授权认证 > http.authorizeRequests() > //设置登录页面允许访问 > .antMatchers("/login.html","/error.html").permitAll() > > //设置所有请求都要被认证 > .anyRequest().authenticated(); > > // CSRF攻击拦截关闭 > http.csrf().disable(); > } > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > > ~~~ ## 自定义登录成功处理器 > 问题域:使用默认successForwardUrl并不能用来跳转到外部地址,也就是跨域访问 > > 例如这样设置成功登陆页进行跳转: > > `successForwardUrl("http://www.baidu.com")`;//结果是跳转失败的,抛出404 > 分析successForwardUrl方法对应的源码,发现底层实际上是调用了successHandler方法 > > ~~~java > public FormLoginConfigurer successForwardUrl(String forwardUrl) { > this.successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl)); > return this; > } > ~~~ > > 继续分析ForwardAuthenticationSuccessHandler源码 > > ~~~java > public class ForwardAuthenticationSuccessHandler implements AuthenticationSuccessHandler { > private final String forwardUrl; > > public ForwardAuthenticationSuccessHandler(String forwardUrl) { > Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), () -> { > return "'" + forwardUrl + "' is not a valid forward URL"; > }); > this.forwardUrl = forwardUrl; > } > > public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { > // 此处实际上就是一个转发 > request.getRequestDispatcher(this.forwardUrl).forward(request, response); > } > } > ~~~ ### 实现步骤 > 编写一个自己的LoginSuccessHanlder去实现AuthenticationSuccessHandler接口 > > ~~~java > package tech.aistar.handler; > > import org.springframework.security.core.Authentication; > import org.springframework.security.core.userdetails.User; > import org.springframework.security.web.authentication.AuthenticationSuccessHandler; > > import javax.servlet.ServletException; > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > import java.io.IOException; > > /** > * 本类用来演示: 登录成功跳转自定义处理器 > * > * @author: success > * @date: 2021/5/28 1:41 下午 > */ > public class LoginSuccessHandler implements AuthenticationSuccessHandler { > private String url; > > public LoginSuccessHandler(String url){ > this.url = url; > } > > @Override > public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { > //此处可以获取登录的用户信息 > User user = (User) authentication.getPrincipal(); > System.out.println("user-username:"+user.getUsername()); > //出于安全性考虑,此处的密码应该是获取不到的 > System.out.println("user-password:"+user.getPassword()); > //获取权限 > System.out.println("user-authentication:"+user.getAuthorities()); > > //重定向到自己的url > httpServletResponse.sendRedirect(url); > } > } > ~~~ > > 修改SecurityConfig.java > > ` .successHandler(new LoginSuccessHandler("http://www.baidu.com"))` > > ~~~java > package tech.aistar.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 tech.aistar.handler.LoginSuccessHandler; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > public class SecurityConfig extends WebSecurityConfigurerAdapter{ > /** > * 注意授权的请求处理,匹配的URL是重定向的地址,而不是控制器的URL。 > * @param http > * @throws Exception > */ > @Override > protected void configure(HttpSecurity http) throws Exception { > //设置登录行为为表单登录 > http.formLogin() > //自定义登录表单的用户名和密码的属性值 > .usernameParameter("uname") > .passwordParameter("pwd") > .loginPage("/login.html") > //此处的/login需要和表单的action的属性值保持一致 > .loginProcessingUrl("/login") > //Security的失败页面跳转也是由配置Bean的方法决定的,请求方式是POST请求 > //所以这个登陆失败的页面跳转也需要一个控制器处理 > //登录成功跳转,post请求 > //.successForwardUrl("/admin/main") > > //使用默认successForwardUrl并不能用来跳转到外部地址,也就是跨域访问 > //例如这样设置成功登陆页进行跳转: > //.successForwardUrl("http://www.baidu.com") > > //设置登录成功自定义处理器 > //注意successForwardUrl和successHandler是不能共存的 > .successHandler(new LoginSuccessHandler("http://www.baidu.com")) > > //登录失败跳转,post请求 > .failureForwardUrl("/admin/error"); > > //授权认证 > http.authorizeRequests() > //设置登录页面允许访问 > .antMatchers("/login.html","/error.html").permitAll() > > //设置所有请求都要被认证 > .anyRequest().authenticated(); > > // CSRF攻击拦截关闭 > http.csrf().disable(); > } > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > ~~~ ## 自定义登录失败处理器 > 问题域同上,查看failureForwardUrl源码,发现底层实际上是调用了failureHandler方法 > > ~~~java > public FormLoginConfigurer failureForwardUrl(String forwardUrl) { > this.failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl)); > return this; > } > ~~~ > > 继续查看ForwardAuthenticationFailureHandler对象源码 > > ~~~ > package org.springframework.security.web.authentication; > > import java.io.IOException; > import javax.servlet.ServletException; > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > import org.springframework.security.core.AuthenticationException; > import org.springframework.security.web.util.UrlUtils; > import org.springframework.util.Assert; > > public class ForwardAuthenticationFailureHandler implements AuthenticationFailureHandler { > private final String forwardUrl; > > public ForwardAuthenticationFailureHandler(String forwardUrl) { > Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), () -> { > return "'" + forwardUrl + "' is not a valid forward URL"; > }); > this.forwardUrl = forwardUrl; > } > > public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { > request.setAttribute("SPRING_SECURITY_LAST_EXCEPTION", exception); > request.getRequestDispatcher(this.forwardUrl).forward(request, response); > } > } ### 实现步骤 > 1. 编写一个自定义的登录失败处理器LoginFailureHandler,去实现AuthenticationFailureHandler接口 > > ~~~java > package tech.aistar.handler; > > 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; > > /** > * 本类用来演示: 登录失败处理器 > * > * @author: success > * @date: 2021/5/28 1:59 下午 > */ > public class LoginFailureHandler implements AuthenticationFailureHandler { > private String url; > > public LoginFailureHandler(String url){ > this.url = url; > } > @Override > public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { > httpServletResponse.sendRedirect(url); > } > } > ~~~ > > 2. 修改SecurityConfig.java > > ` .failureHandler(new LoginFailureHandler("/error.html"));` > > ~~~java > package tech.aistar.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 tech.aistar.handler.LoginFailureHandler; > import tech.aistar.handler.LoginSuccessHandler; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > public class SecurityConfig extends WebSecurityConfigurerAdapter{ > /** > * 注意授权的请求处理,匹配的URL是重定向的地址,而不是控制器的URL。 > * @param http > * @throws Exception > */ > @Override > protected void configure(HttpSecurity http) throws Exception { > //设置登录行为为表单登录 > http.formLogin() > //自定义登录表单的用户名和密码的属性值 > .usernameParameter("uname") > .passwordParameter("pwd") > .loginPage("/login.html") > //此处的/login需要和表单的action的属性值保持一致 > .loginProcessingUrl("/login") > //Security的失败页面跳转也是由配置Bean的方法决定的,请求方式是POST请求 > //所以这个登陆失败的页面跳转也需要一个控制器处理 > //登录成功跳转,post请求 > //.successForwardUrl("/admin/main") > > //使用默认successForwardUrl并不能用来跳转到外部地址,也就是跨域访问 > //例如这样设置成功登陆页进行跳转: > //.successForwardUrl("http://www.baidu.com") > > //设置登录成功自定义处理器 > //注意successForwardUrl和successHandler是不能共存的 > .successHandler(new LoginSuccessHandler("http://www.baidu.com")) > > //登录失败跳转,post请求 > //.failureForwardUrl("/admin/error"); > > //自定义登录失败处理器 > .failureHandler(new LoginFailureHandler("/error.html")); > > //授权认证 > http.authorizeRequests() > //设置登录页面允许访问 > .antMatchers("/login.html","/error.html").permitAll() > > //设置所有请求都要被认证 > .anyRequest().authenticated(); > > // CSRF攻击拦截关闭 > http.csrf().disable(); > } > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > ~~~ ## antMatchers参数讲解 > ~~~java > public C antMatchers(String... antPatterns) {..} > ~~~ > > 参数是不定向参数,每个参数都是一个ant表达式,用于匹配url规则,规则如下: > 1. ? 匹配任意单个字符 > 2. *匹配0或者任意数量的字符 > 3. ** 匹配0或者更多的目录 `在实际项目中经常需要放行所有的静态资源,下面演示js文件夹下所有的js脚本文件` ~~~java .antMatchers("/js/**","/css/**").permitAll(); ~~~ `另外一种方式` ~~~java .antMachers("/**/*.js","/**/*.css").permitAll(); ~~~ ## 如果项目中添加了context-path > 修改login.html的action="/yeb/login" > > 修改配置类 > > ~~~java > package tech.aistar.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.EnableWebSecurity; > import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; > import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; > import tech.aistar.handler.LoginFailureHandler; > import tech.aistar.handler.LoginSuccessHandler; > > /** > * 本类用来演示: SpringSecurity配置类 > * > * @author: success > * @date: 2021/5/26 6:59 下午 > */ > @Configuration > @EnableWebSecurity > public class SecurityConfig extends WebSecurityConfigurerAdapter{ > /** > * 注意授权的请求处理,匹配的URL是重定向的地址,而不是控制器的URL。 > * @param http > * @throws Exception > */ > @Override > protected void configure(HttpSecurity http) throws Exception { > //设置登录行为为表单登录 > http.formLogin() > //自定义登录表单的用户名和密码的属性值 > .usernameParameter("uname") > .passwordParameter("pwd") > .loginPage("/login.html") > //此处的/login需要和表单的action的属性值保持一致 > //此处如果配置了上下文路径,这里是不需要加上/yeb > .loginProcessingUrl("/login") > //Security的失败页面跳转也是由配置Bean的方法决定的,请求方式是POST请求 > //所以这个登陆失败的页面跳转也需要一个控制器处理 > //登录成功跳转,post请求 > //.successForwardUrl("/admin/main") > > //使用默认successForwardUrl并不能用来跳转到外部地址,也就是跨域访问 > //例如这样设置成功登陆页进行跳转: > //.successForwardUrl("http://www.baidu.com") > > //设置登录成功自定义处理器 > //注意successForwardUrl和successHandler是不能共存的 > //.successHandler(new LoginSuccessHandler("http://www.baidu.com")) > .successHandler(new LoginSuccessHandler("/yeb/main.html")) > > //登录失败跳转,post请求 > //.failureForwardUrl("/admin/error"); > > //自定义登录失败处理器 > .failureHandler(new LoginFailureHandler("/yeb/error.html")); > > //授权认证 > http.authorizeRequests() > //设置登录页面允许访问 > .antMatchers("/login.html","/error.html").permitAll() > > //设置所有请求都要被认证 > .anyRequest().authenticated(); > > // CSRF攻击拦截关闭 > http.csrf().disable(); > } > > @Bean > public BCryptPasswordEncoder bCryptPasswordEncoder(){ > return new BCryptPasswordEncoder(); > } > } > ~~~ ## 内置访问控制方法及控制项 > ~~~java > public final class ExpressionUrlAuthorizationConfigurer> extends AbstractInterceptUrlConfigurer, H> { > static final String permitAll = "permitAll"; > private static final String denyAll = "denyAll"; > private static final String anonymous = "anonymous"; > private static final String authenticated = "authenticated"; > private static final String fullyAuthenticated = "fullyAuthenticated"; > private static final String rememberMe = "rememberMe"; > } > ~~~ > > > ``` > > 1. 全部允许 PermiAll > > 2. 全部拒绝 DenyAll > > 3. 允许匿名访问 Anonymous 也就是普通访问者 > > 4. 允许认证之后访问   Authenticated > > 5. 必须完全认证?   FullAuthenticated > > 6. 记住我 RememberMe > > ```