栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringSecurity原理剖析及其实战(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringSecurity原理剖析及其实战(二)

1.Spring Security整合数据库认证服务器

Spring security整合数据库认证本人这边所使用的技术栈如下:

技术描述
mybatis持久层
mybatis-plusMyBatis (opens new window) 的增强工具
hutooljava工具类库
lombok一种 Java™ 实用工具
EasyCode代码生成器

后面的整合oauth2、jwt中也会大量以上技术,包括最后整套Spring Cloud Alibaba - vue前后端分离体系
废话到这,下面正式开始

  • 1.先导入依赖
  

            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            mysql
            mysql-connector-java
        
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.security
            spring-security-test
            test
        
        
        
            org.projectlombok
            lombok
            1.18.6
        
         
        
            cn.hutool
            hutool-all
            5.7.15
        

         
        
            com.baomidou
            mybatis-plus-boot-starter
            3.1.2
        
        
        
            org.apache.velocity
            velocity-engine-core
            2.1
        
        
        
            org.springframework.boot
            spring-boot-devtools
            true
        
        
            junit
            junit
        

整体目录如下,

我这边使用的是EasyCode代码生成器,也可自己去配置mybatis的代码生成器,如需使用EasyCode代码生成器,Plugins 搜索easycode下载重启idea即可

这里分享一下我自定义的模版,只需点击导入模版输入:171c65ee922df8a54fb81abdf018761f,即可使用,如过期评论区下方留言即可,后面会逐步完善模版

EasyCode使用方式如下图,选择服务,生成路径以后需要生成的文件

  • 2.application.yaml的连接池配置如下(数据库表已经在上一章最后面贴出来了)
server:
  port: 8881
  servlet:
      context-path: /
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/hejinwen?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root
    hikari:
      minimum-idle: 5
      idle-timeout: 600000
      maximum-pool-size: 10
      auto-commit: true
      pool-name: MyHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
      connection-test-query: SELECt 1

  • 3.dao/TbPermissionDao.java
package com.csw.jdbc.dao;
 
import com.baomidou.mybatisplus.core.mapper.baseMapper;
import com.csw.jdbc.entity.TbPermission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;
 

@Mapper
public interface TbPermissionDao extends baseMapper {
    
    List selectByUserId(Long userId);
}

mapper/TbPermissionMapper.xml




 
    

   

如下图,主要代码是selectByUserId()方法,其他是EasyCo de生成的方法,后面会逐步完善EasyCode模版:

service/TbPermissionService.java

package com.csw.jdbc.service;
 
import com.csw.jdbc.entity.TbPermission;
import java.util.List;

 
public interface TbPermissionService {
 
    //根据用户id查询
    List  selectByUserId(Long userId);

}

service/impl/TbPermissionServiceImpl.java

package com.csw.jdbc.service.impl;
 
import com.csw.jdbc.dao.TbUserDao;
import com.csw.jdbc.entity.TbPermission;
import com.csw.jdbc.dao.TbPermissionDao;
import com.csw.jdbc.service.TbPermissionService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
 
 
 
@Service
@Transactional 
@AllArgsConstructor
public class TbPermissionServiceImpl implements TbPermissionService {

    private final TbPermissionDao tbPermissionDao;
 
     @Override
     public List selectByUserId(Long userId) {
         return tbPermissionDao.selectByUserId(userId);
     }


 }

dao/TbUserDao.java

package com.csw.jdbc.dao;
 
import com.baomidou.mybatisplus.core.mapper.baseMapper;
import com.csw.jdbc.entity.TbUser;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
 

@Mapper
public interface TbUserDao extends baseMapper {
}

service/TbUserService.java

//根据用户名获取用户信息
    package com.csw.jdbc.service;
 
import com.csw.jdbc.entity.TbUser;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;
 
 
public interface TbUserService {
 
    //根据用户名获取用户信息
    TbUser getByUsername(String username);
 
}

service/impl/TbUserServiceImpl.java(核心代码)

package com.csw.jdbc.service.impl;
 
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.csw.jdbc.dao.TbPermissionDao;
import com.csw.jdbc.entity.TbPermission;
import com.csw.jdbc.entity.TbUser;
import com.csw.jdbc.dao.TbUserDao;
import com.csw.jdbc.service.TbUserService;
import lombok.AllArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
 
 
 
@Service
@Transactional
@AllArgsConstructor
public class TbUserServiceImpl implements TbUserService,UserDetailsService{


    private final TbUserDao tbUserDao;

    private final TbPermissionDao tbPermissionDao;
 
 
     @Override
     public TbUser getByUsername(String username) {
         QueryWrapper wrapper = new QueryWrapper<>();
         wrapper.eq("username",username);
         return this.tbUserDao.selectOne(wrapper);
     }

     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库查用户
        TbUser user = getByUsername(username);
        ArrayList authorities = new ArrayList<>();
        if(user != null) {
            List tbPermissions = tbPermissionDao.selectByUserId(user.getId());

            //设置权限
            tbPermissions.forEach(permissions -> {
                if(permissions != null && !StrUtil.isEmpty(permissions.getEnname())) {
                    SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permissions.getEnname());
                    authorities.add(grantedAuthority);
                }
            });
            //封装成UserDetails的实现类
            return new org.springframework.security.core.userdetails.User(
                    user.getUsername(),user.getPassword(),authorities);
        }else {
            throw new UsernameNotFoundException("用户名不存在");
        }
     }
 }

entity/TbUser.java

package com.csw.jdbc.entity;

import java.util.Date;
import java.io.Serializable;
import lombok.*;

@Data
public class TbUser implements Serializable {
    private static final long serialVersionUID = 734210779083900189L;

        private Long id;

        private String username;

        private String password;

        private String phone;

        private String email;

        private Date created;

        private Date updated;
}

entity/TbRole.java

package com.csw.jdbc.entity;

import java.util.Date;
import java.io.Serializable;
import lombok.*;

@Data
public class TbRole implements Serializable {
    private static final long serialVersionUID = 768391666783014299L;

        private Long id;

        private Long parentId;

        private String name;

        private String enname;

        private String description;

        private Date created;

        private Date updated;
}

entity/TbPermission.java

package com.csw.jdbc.entity;

import java.util.Date;
import java.io.Serializable;
import lombok.*;

@Data
public class TbPermission implements Serializable {
    private static final long serialVersionUID = -91733717429724780L;

        private Long id;

        private Long parentId;

        private String name;

        private String enname;

        private String url;

        private String description;

        private Date created;

        private Date updated; 
}

以上代码都可以使用EasyCode或者其他代码生成器生成的,核心代码只有TbUserServiceImpl.java里面的…
config/WebSecurityConfig.java

package com.csw.jdbc.config;

import com.csw.jdbc.service.impl.TbUserServiceImpl;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private TbUserServiceImpl userServiceImpl;


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //设置UserDetailsService的实现类
        auth.userDetailsService(userServiceImpl);
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

到这里注意,我已经在TbUserServiceImpl去实现了UserDetailsService接口的loadUserByUsername方法

整体代码已上传至(https://gitee.com/JAVA8888/spring-security.git),顺便在这里打个广告,推荐一个不错的SpringCloud Alibaba + vue项目(https://gitee.com/youlaitech/youlai-mall)
我们试下登录后的效果:

debug登录认证效果如下图:

以上就是Spring security整合数据库认证,都是一些比较基础的东西,为整合Oauth2打下点基础,争取下篇把Spring Security完结了,喜欢的朋友点个关注,您的关注或点赞都是博主的动力

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396628.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号