zoukankan      html  css  js  c++  java
  • springsecrity入门demo 认证

    创建一个springboot项目

    springboot版本依赖 使用 2.3.12.RELEASE

     <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.2</version>
            </dependency>
        </dependencies>
    
    

    用户表

    DROP TABLE IF EXISTS `t_admin`;
    CREATE TABLE `t_admin`  (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `create_time` bigint(32) NOT NULL COMMENT '创建时间',
      `enabled` tinyint(2) NOT NULL DEFAULT 0 COMMENT '是否启用: 0 不启动,1 启用',
      `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
      `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
      `update_time` bigint(32) NOT NULL COMMENT '更新时间',
      `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'Admin对象 用户表' ROW_FORMAT = Dynamic;
    

    配置文件

    spring:
      datasource:
        name: 
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://:3310/?characterEncoding=utf8&useSSL=false
        username: root
        password: 密码
    

    创建用户类

    
    public class Admin implements Serializable, UserDetails {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
        private Long createTime;
        private boolean enabled;
        private String name;
        private String password;
        private Long updateTime;
        private String username;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public Long getCreateTime() {
            return createTime;
        }
        public void setCreateTime(Long createTime) {
            this.createTime = createTime;
        }
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public Long getUpdateTime() {
            return updateTime;
        }
        public void setUpdateTime(Long updateTime) {
            this.updateTime = updateTime;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        @Override
        public String toString() {
            return "Admin{" +
                    "id=" + id +
                    ", createTime=" + createTime +
                    ", enabled=" + enabled +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    ", updateTime=" + updateTime +
                    ", username='" + username + '\'' +
                    '}';
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return null;
        }
        @Override
        public String getPassword() {
            return password;
        }
        @Override
        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 this.enabled;
        }
    }
    
    

    新建mapper

    public interface AdminMapper extends BaseMapper<Admin> {
    
        @Select("select * from t_admin " +
                "${ew.customSqlSegment}")
        Admin getAllAdmins(@Param(Constants.WRAPPER) Wrapper wrapper);
    
    }
    
    

    service

    public interface IAdminService extends IService<Admin> {
    
        Admin getAllAdmins(String name);
    
    }
    
    @Service
    public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {
    
        @Resource
        private AdminMapper adminMapper;
    
        public Admin getAllAdmins(String name) {
            System.out.println(name);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("name",name);
            return adminMapper.getAllAdmins(queryWrapper);
        }
    }
    

    新建UserServiceImpl 实现UserDetailsService

    这里实现通过查询数据库返回密码到密码验证类

    @Service
    public class UserServiceImpl implements UserDetailsService {
    
        @Autowired
        private AdminServiceImpl adminService;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            //数据库查询
            Admin allAdmins = adminService.getAllAdmins(username);
    
            //1.根据username查询数据库
            if(allAdmins==null){
                throw new UsernameNotFoundException("用户名或密码错误");
            }
            return new User(allAdmins.getName(), allAdmins.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        }
    }
    

    新建config需要两个配置类

    密码校验UserAuthenticationProvider

    把上一个UserDetailsService 类注入进来
    重点是这个 方法 bCryptPasswordEncoder.matches(password, userDetails.getPassword());

    /**
     * 完成校验工作
     */
    @Component
    public class UserAuthenticationProvider  implements AuthenticationProvider {
        @Autowired
        private UserDetailsService userDetailService;
    
        /**
         * 进行身份认证
         *
         * @param authentication
         * @return
         * @throws AuthenticationException
         */
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            System.out.println("进行身份认证");
            // 获取用户输入的用户名和密码
            String username = authentication.getName();
            String password = authentication.getCredentials().toString();
            System.out.println(username);
            // 获取封装用户信息的对象
            UserDetails userDetails = userDetailService.loadUserByUsername(username);
            System.out.println("   ===========   权限:"+userDetails.getAuthorities());
            // 进行密码的比对
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            boolean flag = bCryptPasswordEncoder.matches(password, userDetails.getPassword());
            // 校验通过
            if (flag){
                // 将权限信息也封装进去
                return new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,rzk"));
            }
            // 验证失败返回 null
            return null;
        }
    
        /**
         * 这个方法 确保返回 true 即可,
         *
         * @param aClass
         * @return
         */
        @Override
        public boolean supports(Class<?> aClass) {
            return true;
        }
    }
    

    SecurityConfig

    
    /**
     * @PackageName : com.rzk.config
     * @FileName : SecurityConfig
     * @Description :
     * @Author : rzk
     * @CreateTime : 13/12/2021 下午10:19
     * @Version : v1.0
     */
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            System.out.println("执行自定义登录逻辑方法");
            //表单登录
            http.formLogin()
                    //自定义登录页面
                    .loginPage("/login.html")
                    //自定义登录逻辑
                    .loginProcessingUrl("/login")
                    //登录成功后跳转的页面,必须是post
                    .successForwardUrl("/toMain")
                    //登录失败后跳转页面,必须是post
                    .failureForwardUrl("/toError");
    
            //授权
            http.authorizeRequests()
                    //放行页面
                    .antMatchers("/login.html").permitAll()
                    .antMatchers("/error.html").permitAll()
                    //所有请求都必须被认证(登录)
                    .anyRequest().authenticated();
    
            //关闭csrf防护
            http.csrf().disable();
        }
    
        @Bean
        public PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
    }
    
    

    controller

    @Controller
    public class LoginController {
    
        @Autowired
        private IAdminService adminService;
        @Autowired
        private PasswordEncoder passwordEncoder;
        @Autowired
        private UserDetailsService userDetailsService;
    
        @RequestMapping("/login")
        public String login(@RequestParam("username") String username, @RequestParam("password")String password){
            Admin allAdmins = adminService.getAllAdmins(username);
            //登录
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (userDetails == null || !passwordEncoder.matches(password,allAdmins.getPassword())){
                System.out.println("空");
            }
            return "redirect:main.html";
        }
    
        @RequestMapping("/toMain")
        public String toMain(){
            return "redirect:main.html";
        }
    
        @RequestMapping("/toError")
        public String error(){
            return "redirect:error.html";
        }
    }
    
    

    这里需要三个html页面

    error.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    登录失败
    </body>
    </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="password"name="password"/><br/>
        <input type="submit"value="登录"/><br/>
    </form>
    </body>
    </html>
    

    main.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>登录成功</h1>
    </body>
    </html>
    

    还没登录如果访问登录成功页面 是访问不了的

  • 相关阅读:
    多层动态库的编译及使用
    gxx -L和/etc/ld.so.conf的理解
    cmake 创建并调用动态库和静态库
    cifX驱动安装及SYCON.net的使用
    企业号新手指引
    转:Python正则表达式指南
    Windows平台安装Beautiful Soup
    微信企业号、订阅号、服务号之间有什么区别和不同
    常见HTTP状态(304,200等)
    微信内置浏览器对于html5的支持
  • 原文地址:https://www.cnblogs.com/rzkwz/p/15704260.html
Copyright © 2011-2022 走看看