搭建一个多模块系统--admin后台的一些配置(三)

发布时间 2023-05-26 18:12:44作者: 与f

搭建一个多模块系统--admin后台的一些配置 testblog-admin (验证打算用springboot+Security+Thymeleaf)

 

1. pom.xml 文件

        <!--SpringSecurity启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--对Thymeleaf添加Spring Security标签支持-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

 

2. application.properties

# 后缀
spring.thymeleaf.prefix=classpath: /templates
# 模板格式
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.suffix=.html
# 开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false

2. application.yml

# 项目相关配置
testBlog:
  # 名称
  name: qiqi
  # 版本
  version: 1.0.0
  # 版权年份
  copyrightYear: 2023
  # 实例演示开关
  demoEnabled: true
  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/ruoyi/uploadPath
  # 获取ip地址开关
  addressEnabled: false
  # 验证码类型 math 数组计算 char 字符验证
  captchaType: math



# 开发环境配置
server:
  # 服务器的HTTP端口,默认为8081
  port: 8081
  servlet:
    # 应用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # 连接数满后的排队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100


# Spring配置
spring:
  # 资源信息
  messages:
    # 国际化资源文件路径
    basename: i18n/messages
  profiles:
    active:
  # 文件上传
  servlet:
    multipart:
      # 单个文件大小
      max-file-size:  10MB
      # 设置总上传的文件大小
      max-request-size:  20MB
  # 服务模块
  devtools:
    restart:
      # 热部署开关
      enabled: true
  # 原生数据库连接配置
  datasource:
    url: jdbc:mysql://localhost:3306/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 89757
    driverClassName: com.mysql.cj.jdbc.Driver
  # redis 配置
  redis:
    # 地址
    host: localhost
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 密码
    password:
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池的最大数据库连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
  # thymeleaf后缀
  thymeleaf:
    prefix: classpath:/templates
    # 模板格式
    mode: HTML5
    encoding: UTF-8
    content-type: text/html
    suffix: .html
    # 开发时关闭缓存,不然没法看到实时页面
    cache: false


# MyBatis配置
mybatis:
  # 搜索指定包别名
  typeAliasesPackage: com.qiqi.**.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 加载全局的配置文件
  configLocation: classpath:mybatis/mybatis-config.xml

# MyBatis Plus配置
mybatis-plus:
  global-config:
    # 设置表前缀
    db-config:
      # 表名前缀
      table-prefix: tb_
      # id生成策略自动增长
      id-type: auto
      # sql日志打印
      log-impl:  org.apache.ibatis.logging.stdout.StdOutImpl

# 日志配置
logging:
  config: classpath:logback-spring.xml
  level:
    com.ruoyi: debug
    org.springframework: warn

# Swagger配置
swagger:
  # 是否开启swagger
  enabled: true
  # 请求前缀
  pathMapping: /dev-api


# 用户配置
user:
  password:
    # 密码最大错误次数
    maxRetryCount: 5
    # 密码锁定时间(默认10分钟)
    lockTime: 10

3.安全相关的配置  SecurityWebConfig

/**
 * web的安全配置
 */

@Configuration
@EnableWebSecurity    // 添加 security 过滤器
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)    // 启用方法级别的权限认证
public class SecurityWebConfig {

    @Autowired(required=true)
    public UserDetailsService userDetailsServiceImpl;

    /**
     * 获取AuthenticationManager(认证管理器),登录时认证使用
     * @param authenticationConfiguration
     * @return
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }


    /**
     * anyRequest          |   匹配所有请求路径
     * access              |   SpringEl表达式结果为true时可以访问
     * anonymous           |   匿名可以访问
     * denyAll             |   用户不能访问
     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
     * permitAll           |   用户可以任意访问
     * rememberMe          |   允许通过remember-me登录的用户访问
     * authenticated       |   用户登录后可访问
     */

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 注解标记允许匿名访问的url
        //ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
        //permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());

        http
            // 基于 web,需要 csrf (其实不用配置,默认支持)
            .csrf().and()
            // 基于 web,需要 session  (其实不用配置,默认支持)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS).and()

            // 下面开始设置权限过滤请求
            .authorizeRequests(authorize -> authorize
                    // 请求放开
                    .antMatchers("/index","/index1","/index2").permitAll()
                    // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                    .antMatchers("/login", "/register", "/captchaImage").permitAll()
                    // 静态资源,可匿名访问
                    .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                    // 其他地址的访问均需验证权限
                    .anyRequest().authenticated()
            )
            // 认证用户时用户信息加载配置,注入springAuthUserService  (其实不用配置,默认实现接口即可调用)
            .userDetailsService(userDetailsServiceImpl);

        //请求过滤规则

        //指定登录表单的规则
        http.formLogin()
            //这个路径必须和登录表单的提交路径一致。
            .loginProcessingUrl("/login")
            //设置自定义登录界面
            .loginPage("/login.html")
            //登录成功后转发的路径
            .successForwardUrl("/main")
            .permitAll();

        //登出配置
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/").clearAuthentication(true);

        //记住我功能

        //没有权限时跳转的路径
        http.exceptionHandling().accessDeniedPage("/403.html");

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return  new BCryptPasswordEncoder();
    }

    /**
     * 配置跨源访问(CORS)
     * @return
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    }



}

 4. UserDetailsServiceImpl

@Service("userDetailsServiceImpl")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private PermissionDao permissionDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.根据账户查询用户信息.
        QueryWrapper<MyUser> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",username);
        MyUser myUser = userDao.selectOne(queryWrapper);
        if(myUser!=null){
            //2. 查询改用户具有的权限。
            List<Permission> permissions = permissionDao.findByUserid(myUser.getUserid());
            //返回UserDetails对象---它是一个接口,返回它的实现类。

//            String username,账户
//            String password,密码数据库中的密码
//            authorities: 该用户具有的权限

            Collection<? extends GrantedAuthority> authorities=permissions.stream().map(item->new SimpleGrantedAuthority(item.getPerCode())).collect(Collectors.toList());
            User user=new User(username,myUser.getPassword(),authorities);
            return user;
        }
        return null;
    }


}