三分钟快速上手SpringSecurity框架

导入依赖框架

web 框架(spring-boot-starter-web)

java 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

springSecurity 框架(spring-boot-starter-security)

java 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

导入框架之后、当前应用已经具备验证功能

用户名默认为user、密码为启动窗口打印信息

默认登陆页(存在问题、每次需要记录登录密码)

配置文件配置固定用户名、密码


自定义功能实现(用户信息从数据库获取)

方式一:

导入数据源依赖 mysql\mybatis,配置数据源信息

java 复制代码
  <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>


2.

直接配置查询 sql (select username,password from s_usr where username = ?)

java 复制代码
package com.bu.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

/**
 * @author haizhuangbu
 * @date 2024/5/15 16:35
 * @mark WebSecurityConfigImpl
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
                // 配置数据源
                .dataSource(dataSource)
                // 查询sql
                .usersByUsernameQuery("select username,password,'Y' enabled from s_usr where username = ?")
                .authoritiesByUsernameQuery("select username,authority\n" +
                        "from authorizes where username = ?");
    }


    // 不进行解密、直接对比
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

}

此时用户信息就是去数据库查询的 (用户信息表 创建包含用户密码关键字段即可)

sql 复制代码
create table s_usr
(
    user_id     varchar(36) not null
        primary key,
    username    varchar(36) null,
    password    varchar(36) null,
    create_time datetime    null,
    modify_time datetime    null,
    enable      char(2)     null comment 'Y 生效 N 失效'
);



create table authorizes
(
    username  varchar(36),
    authority varchar(36)
);



insert into s_usr
values ('1', 'admin', 'admin', now(), now(), 'Y');

方式二:

导入数据源配置信息同方式一相同

重写springSecurity 的几个组件

  1. UserDetailsService 用户信息查询接口(内部具体编写查询逻辑 )

    sql 复制代码
    package com.bu.config;
    
    import com.bu.sys.user.dao.UserDetailsDao;
    import com.bu.sys.user.dto.SUsrDto;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Component;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 16:22
     * @mark AuthUserServiceImpl
     */
    @Component
    public class AuthUserServiceImpl implements UserDetailsService {
    
    
        @Autowired
        private UserDetailsDao userDetailsDao;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            SUsrDto sUsrDto = userDetailsDao.findSUsrByUsername(username);
            return sUsrDto;
        }
    }
    
    
    
    package com.bu.sys.user.dao;
    
    import com.bu.sys.user.dto.SUsrDto;
    import org.apache.ibatis.annotations.Select;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 17:15
     * @mark UserDetailsDao
     */
    public interface UserDetailsDao {
    
        @Select("select * from s_usr where username = #{username}")
        SUsrDto findSUsrByUsername(String username);
    
    }
  2. PasswordEncoder 加解密工具

    java 复制代码
        // 不进行解密、直接对比
        @Bean
        public PasswordEncoder passwordEncoder() {
            return NoOpPasswordEncoder.getInstance();
        }
  3. UserDetail 用户信息

    java 复制代码
    package com.bu.sys.user.dto;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.Collection;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 17:16
     * @mark SUsrDto
     */
    public class SUsrDto implements UserDetails {
    
        private String username;
    
        private String password;
    
    
        public String getUsername() {
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return null;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
  4. AuthenticationProvider 验证流程

    java 复制代码
    package com.bu.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.AuthenticationProvider;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    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.Component;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 17:20
     * @mark UserAutorizedServiceImpl
     */
    @Component
    public class UserAuthorizedServiceImpl implements AuthenticationProvider {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    
            // 查询用户信息
            UserDetails userDetails = userDetailsService.loadUserByUsername(authentication.getName());
    
            if (userDetails == null) {
                throw new UsernameNotFoundException("用户信息不存在");
            }
    
    
            if (!passwordEncoder.matches(userDetails.getPassword(), (String) authentication.getCredentials())) {
    
                throw new UsernameNotFoundException("密码不正确");
    
            }
    
            return new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());
        }
    
        @Override
        public boolean supports(Class<?> aClass) {
            return true;
        }
    }

验证组件交给springSecurity (同数据源方式类似)

java 复制代码
package com.bu.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

/**
 * @author haizhuangbu
 * @date 2024/5/15 16:35
 * @mark WebSecurityConfigImpl
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserAuthorizedServiceImpl userAuthorizedService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(userAuthorizedService);
    }




}

配置其他信息(成功跳转、失败跳转....)

java 复制代码
   // 非页面列表页可以无权限访问外、其他都需要验证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // permitAll 放行路径
                .antMatchers("/login", "/blogs/listAllBlogs", "/blogs/listBloggerInfo", "/theme/listAll")
                .permitAll()
                .anyRequest().authenticated()
                .and().formLogin() // 默认 login 登陆路径
                .failureHandler(failLoginHandler)// 成功处理逻辑
//                .defaultSuccessUrl("/success")
//                .failureUrl("/error")
                .and().addFilterAfter(tokenFilter, BasicAuthenticationFilter.class)
        ;

        http.csrf().disable();

        http.cors().disable();
    }

详细配置思维导图

相关推荐
正小安28 分钟前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
2402_8575893628 分钟前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰1 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没2 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch2 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光2 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   2 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   2 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
编程、小哥哥2 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
Fan_web2 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery