springboot+security 数据库中读取帐号密码 使用security加密规则 实体类不继承security的实体接口

项目存放位置

        码云地址:https://gitee.com/huatao1994/springSecuritycss

1、项目结构

            

2、数据库设计

        

        

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50529
Source Host           : localhost:3306
Source Database       : security

Target Server Type    : MYSQL
Target Server Version : 50529
File Encoding         : 65001

Date: 2019-12-21 14:04:04
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `authority_menu`
-- ----------------------------
DROP TABLE IF EXISTS `authority_menu`;
CREATE TABLE `authority_menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `url` varchar(255) DEFAULT NULL COMMENT '请求路径',
  `menu_name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
  `parent_id` int(11) DEFAULT NULL COMMENT '父菜单id',
  `update_time` varchar(255) DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `url_pre` varchar(255) DEFAULT NULL COMMENT '路由(前端本身匹配用)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authority_menu
-- ----------------------------


-- ----------------------------
-- Table structure for `authority_role`
-- ----------------------------
DROP TABLE IF EXISTS `authority_role`;
CREATE TABLE `authority_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `role_name` varchar(255) DEFAULT NULL COMMENT '角色名称(必须以ROLE_起始命名)',
  `role_name_CN` varchar(255) DEFAULT NULL COMMENT '角色名称中文',
  `update_time` varchar(255) DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authority_role
-- ----------------------------


-- ----------------------------
-- Table structure for `authority_role_menu`
-- ----------------------------
DROP TABLE IF EXISTS `authority_role_menu`;
CREATE TABLE `authority_role_menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `role_id` int(11) DEFAULT NULL,
  `menu_id` int(11) DEFAULT NULL,
  `update_time` varchar(255) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authority_role_menu
-- ----------------------------


-- ----------------------------
-- Table structure for `authority_user`
-- ----------------------------
DROP TABLE IF EXISTS `authority_user`;
CREATE TABLE `authority_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `username` varchar(255) DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) DEFAULT NULL COMMENT '密码',
  `email` varchar(255) DEFAULT NULL COMMENT '邮箱',
  `phone` varchar(255) DEFAULT NULL COMMENT '手机号',
  `valid_time` varchar(255) DEFAULT NULL COMMENT '有效截止时间',
  `update_time` varchar(255) DEFAULT NULL COMMENT '更新时间',
  `remark` mediumtext COMMENT '备注',
  `nickname` varchar(255) DEFAULT NULL COMMENT '昵称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authority_user
-- ----------------------------


-- ----------------------------
-- Table structure for `authority_user_role`
-- ----------------------------
DROP TABLE IF EXISTS `authority_user_role`;
CREATE TABLE `authority_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_id` int(11) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  `update_time` varchar(255) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authority_user_role
-- ----------------------------


-- ----------------------------
-- Table structure for `persistent_logins`
-- ----------------------------
DROP TABLE IF EXISTS `persistent_logins`;
CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of persistent_logins
-- ----------------------------

3、controller

            一、UserController 

package cn.**.controller;

import cn.**.dao.UserDao;
import cn.**.service.UserService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.controller
 * @Author: huat
 * @Date: 2019/12/12 14:56
 * @Version: 1.0
 */
@RestController
public class UserController {
    @Autowired
    UserService1 userService1;

    //@Secured("ROLE_ADMIN")//security权限注解
    //@RolesAllowed("ROLE_ADMIN") //jsr250注解
    //@PreAuthorize("hasRole('ROLE_ADMIN')")//spring的注解
    @RequestMapping("/login")
    public String login(String username,String password){
        //获取登录的用户名
        String username1= SecurityContextHolder.getContext().getAuthentication().getName();
        System.out.println(username);
        return "index";
    }
    @RequestMapping("test")
    public String test(){
        return "hello test";
    }


}

        二、IntoController 

package cn.**.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.controller
 * @Author: huat
 * @Date: 2019/12/16 15:16
 * @Version: 1.0
 */
@Controller
public class IntoController {

    @RequestMapping("intoTest")
    public String intoTest(){
        return "/test";
    }
    @RequestMapping("intoIndex")
    public String intoIndex(){
        return "index";
    }
    @RequestMapping("intoFail")
    public String intoFail(){
        return "fail";
    }
    @RequestMapping("intoLogin")
    public String intoLogin(){
        return "login";
    }

    @RequestMapping("dologin")
    public String dologin(){
        return "index";
    }

}

4、entity

        一、AuthorityUser

package cn.**.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.List;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.entity
 * @Author: huat
 * @Date: 2019/12/12 15:12
 * @Version: 1.0
 * 建立实体类第一种方式
 */
public class AuthorityUser1 {
    private int id;
    private String username;
    private String password;
    private List<AuthorityRole> authorityRoles;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<AuthorityRole> getAuthorityRoles() {
        return authorityRoles;
    }

    public void setAuthorityRoles(List<AuthorityRole> authorityRoles) {
        this.authorityRoles = authorityRoles;
    }

}

           二、AuthorityRole

package cn.**.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.entity
 * @Author: huat
 * @Date: 2019/12/12 16:14
 * @Version: 1.0
 */
public class AuthorityRole1  {
    private int id;
    private String roleName;
    private String roleNameCN;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleNameCN() {
        return roleNameCN;
    }

    public void setRoleNameCN(String roleNameCN) {
        this.roleNameCN = roleNameCN;
    }


}

           三、AuthorityMenu

package cn.**.entity;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.entity
 * @Author: huat
 * @Date: 2019/12/16 18:45
 * @Version: 1.0
 */
public class AuthorityMenu1 {
    private  int id;
    private String url;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

5、service

           一、UserService

package cn.**.service;

import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.service
 * @Author: huat
 * @Date: 2019/12/12 17:35
 * @Version: 1.0
 */
//UserDetailsService 是security中的类
public interface UserService extends UserDetailsService {


}

          二、UserServiceImpl

package cn.**.service;




import cn.**.dao1.*;
import cn.**.entity.AuthorityRole1;
import cn.**.entity.AuthorityUser1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.utile
 * @Author: huat
 * @Date: 2019/12/12 14:48
 * @Version: 1.0
 */
@Service//将这个类注入到spring容器中
public class UserService1Impl implements UserService1 {

    @Autowired
    private UserDao1 userDao1;//获取用户
    @Autowired
    private RoleDao1 roleDao1;//获取角色
    @Autowired
    private MenuDao1 menuDao1;//获取路径集合
    @Autowired
    private PasswordEncoder myPasswordEncoder; //使用springSecurity加密规则




    //@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       try{
           //根据用户名查询用户
           AuthorityUser1 authorityUser =userDao1.getUser(username);
           if(null== authorityUser){
               //返回null表明验证失败
               return null;
           }
           //放角色的集合
           List<SimpleGrantedAuthority> authorities=new ArrayList<SimpleGrantedAuthority>();
           List<AuthorityRole1> roleList=roleDao1.getAllRole(authorityUser.getId());
           //list中放入角色权限
          if(null!=roleList&&roleList.size()>0){
              for (AuthorityRole1 role:roleList) {
                  authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
              }
          }
           //{noop}表明使用明文验证
         // UserDetails userDetails=new User(authorityUser.getUsername(),"{noop}"+authorityUser.getPassword(),authorities);
           //使用密文验证
           UserDetails userDetails=new User(authorityUser.getUsername(),authorityUser.getPassword(),authorities);
          return userDetails;
       }catch (Exception e){
           e.printStackTrace();
           //返回null表明验证失败
           return null;
       }

    }

    public static void main(String[] args) {
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        //passwordEncoder.encode("123456")加密方法
        //执行屡次加密后的结果均不同
        //执行第一次:$2a$10$RSlzzO4xAubBLZMB8jPL8eMFX17gM61JfrgINpzOiaEsBdtKBuSDe
        //执行第二次:$2a$10$2uQWdP9qAXGK4H0um0gtG.o1QzbGhBlbxx8YjX526jIrVBNKyziFe
        //执行第三次:$2a$10$8CWttAISfamloSErsqEAPemALyZvj8VWaUCBJKcm2GE1dhFR.7oYG
        //security加密方式是动态加盐
        System.out.println(passwordEncoder.encode("123456"));
        //比较明文和密文是否一致
        System.out.println(passwordEncoder.matches("123456","$2a$10$lstWyJ6NlbdZ2uVr8ncsHOUKsG0VAT4FzDdy0gqy6gbaOqpp6ouDq"));
    }


}

6、dao

          一、UserDao

package cn.**.dao;

import cn.**.entity.AuthorityUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.dao
 * @Author: huat
 * @Date: 2019/12/12 15:04
 * @Version: 1.0
 */
@Mapper
public interface UserDao {
    /**
     * 根据用户名查询角色
     * @param username 用户名
     * @return
     */
    AuthorityUser getUser(@Param("username") String username);

    /**
     * 添加用户
     * @param username 用户名
     * @param password  密码
     * @return
     */
    int saveUser(@Param("username") String username, @Param("password") String password);
}

          UserDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.**.dao1.UserDao1">
    <select id="getUser" resultType="authorityUser1">
        select * from authority_user where username=#{username}
    </select>
    <insert id="saveUser">
        insert into authority_user(username,password) values(#{username},#{password})
    </insert>
</mapper>

          二、RoleDao1

package cn.**.dao1;

import cn.**.entity.AuthorityRole;
import cn.**.entity.AuthorityRole1;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.dao
 * @Author: huat
 * @Date: 2019/12/12 16:15
 * @Version: 1.0
 */
@Mapper
public interface RoleDao1 {
    //根据用户id获取对应的权限
    List<AuthorityRole1> getAllRole(@Param("id") int id);
}

          RoleDao1.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.**.dao1.RoleDao1">
    <select id="getAllRole" resultType="authorityRole1">
       SELECT r.id,r.role_name roleName FROM authority_user_role a
       LEFT JOIN authority_user u ON u.id=a.user_id
       LEFT JOIN authority_role r ON r.id=a.role_id
       WHERE u.id=#{id}
    </select>
</mapper>

          三、MenuDao1

package cn.**.dao1;

import cn.**.entity.AuthorityMenu;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.dao
 * @Author: huat
 * @Date: 2019/12/17 11:31
 * @Version: 1.0
 */
@Mapper
public interface MenuDao1 {
    /**
     * 根据角色id查询全部路径
     * @param roleId 角色id
     * @return
     */
    List<AuthorityMenu> getMenuById(@Param("roleId") int roleId);
}

          MenuDao1.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.**.dao1.MenuDao1">
    <select id="getMenuById" resultType="authorityMenu1">
       select m.url,m.menu_name name,m.id from authority_role r
        LEFT JOIN authority_role_menu rm ON rm.role_id=r.id
        LEFT JOIN authority_menu m ON rm.menu_id=m.id
        where r.id=#{roleId}
    </select>
</mapper>

7、SpringSercurityConfig

package cn.**.util;


import cn.**.service.UserService;
import cn.**.service.UserService1;
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.method.configuration.EnableGlobalMethodSecurity;
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 org.springframework.security.crypto.password.PasswordEncoder;


/**
 * @ProjectName: springbootSecurity
 * @Package: cn.**.security.util
 * @Author: huat
 * @Date: 2019/12/14 8:06
 * @Version: 1.0
 */

/**
 * 开启security注解支持
 * @EnableWebSecurity
 * (securedEnabled=true) 开启@Secured 注解过滤权限
 * (jsr250Enabled=true)开启@RolesAllowed 注解过滤权限
 * (prePostEnabled=true) 使用表达式时间方法级别的安全性         4个注解可用
 * @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true)
 */
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true)
public class SpringSercurityConfig extends WebSecurityConfigurerAdapter {
   /* @Autowired
    UserService1 userService;*/
   @Autowired
   UserService userService;

    /**
     * 将security中加密方式注入到spring容器中
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * 将帐号密码设置在数据库当中
     * @param auth
     * @throws Exception
     */
    @Override
    public  void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth
       //将UserDetailsService放到容器中
       .userDetailsService(userService)
       //加密方式放入
       .passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //释放静态资源,指定资源拦截规则,
        // 指定自定义认证页面,指定退出认证配置,csrf(跨域伪造请求)配置
        http.authorizeRequests()
                .antMatchers("intoLogin","login.jsp","/css/**","fail.jsp","/intoIndex","/index.jsp").permitAll()//释放这些资源,容许匿名访问
               .antMatchers("/**").hasAnyRole("ADMIN","USER")
                .anyRequest().authenticated()//其余资源须要认证
                .and()
                .formLogin()
                .loginPage("/intoLogin")//登录页请求的接口
                .loginProcessingUrl("/dologin")//登录地址,由springSecurity提供
                .successForwardUrl("/intoTest")//登录成功
                .failureForwardUrl("/intoFail")//登陆失败
                .permitAll()//指定全部资源释放
                .and()
                .logout()//登出
                .logoutUrl("/logout")//指定登出路径
                .logoutSuccessUrl("/login.jsp")//登出成功后跳转的url
                .invalidateHttpSession(true)//是否清空session
                .permitAll()
                .and()
                .csrf()
                .disable();//关闭csrf(跨域伪造请求)
    }
/*  *//**
     * ajax 登录
     * @param http
     * @throws Exception
     *//*
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //释放静态资源,指定资源拦截规则,
        // 指定自定义认证页面,指定退出认证配置,csrf(跨域伪造请求)配置
        http.authorizeRequests()
                .antMatchers("intoLogin","login.jsp","/css/**","fail.jsp","/intoIndex","/index.jsp").permitAll()//释放这些资源,容许匿名访问
               .antMatchers("/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/test").hasRole("USER")
                .anyRequest().authenticated()//其余资源须要认证
                .and()
                .formLogin()
                .loginPage("/intoLogin")//登录页请求的接口
                .successHandler(authenticationSuccessHandler)//登录成功后返回的数据
                .failureHandler(authenticationFailureHandler)
                .loginProcessingUrl("/login")//登录地址,由springSecurity提供
                .usernameParameter("name")
                .passwordParameter("pwd")
                .permitAll()//指定全部资源释放
                .and()
                .logout()//登出
                .logoutUrl("/logout")//指定登出路径
                .logoutSuccessUrl("/login.jsp")//登出成功后跳转的url
                .invalidateHttpSession(true)//是否清空session
                .permitAll()
                .and()
                .cors()
                .and()
                .csrf()
                .disable()

                ;//关闭csrf(跨域伪造请求)
    }*/
}
相关文章
相关标签/搜索