SpringBoot 2.0 | Security+Mybatis 权限认证

1.简介

Spring Security 是 Spring 家族的一个安全框架, 提供了全面的安全解决方案 , 对用户的身份进行认证, 以及验证每一个用户所具有的的权限, 根据用户的权限限制用户的操作。

Mybatis 是一款优秀的持久层框架 , 支持自定义 SQL 以及各种高级映射 , 与 JPA 的自动生成 SQL 相比, 它更加灵活, 本例使用 Mybatis 存储用户的身份和权限, 通过 Security 获取用户信息, 对用户的权限和操作进行管理。

2.实现代码

1.项目配置

spring:
  datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      username: root
      password: roof
      url: jdbc:mysql://localhost:3306/security?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true

    # 配置前端Thymeleaf模板引擎
  thymeleaf:
  # 打包末尾无/
    prefix: classpath:/templates/
    check-template-location: true
    suffix: .html
    encoding: UTF-8
    servlet:
      content-type: text/html
    mode: HTML5
    # 禁止后实现前端热部署
    cache: false

# 集成Mybatis
mybatis:
  # Mybatis映射
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.hly.springBootSecurityMybatis.entity

# 端口设置
server:
  port: 8081

2.Security 配置

@Configuration
@EnableWebSecurity//开启WebSecurity功能
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启方法上的保护
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Bean
   UserDetailsService userService(){
       return  new UserService();
   }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        //从数据库中获取用户认证信息
        auth.userDetailsService(userService());
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //不需要验证的资源
                .antMatchers("/css/**", "/index").permitAll()
                //需要验证,角色为Role
                .antMatchers("/article/**").hasAnyRole("ADMIN","STUDENT","TEACHER")
                .antMatchers("/admin/**").hasAnyRole("ADMIN","STUDENT","TEACHER")
                .and()
                //表单的登录地址和失败地址
                .formLogin().loginPage("/login").failureForwardUrl("/loginError")
                .and()
                //异常处理界面
                .exceptionHandling().accessDeniedPage("/401");
        http.logout().logoutSuccessUrl("/");
    }
}

3.controller 层

@Controller
public class ArticleController {

    @Autowired
    ArticleService articleService;
    /**
     * 查看文章列表
     * @param model
     * @return
     */
    @RequestMapping("/article")
    public ModelAndView articleList(Model model){
        List
list = articleService.getArticles(); model.addAttribute("articlesList",list); return new ModelAndView("article/list","articleModel",model); } /** * 给方法设置权限,没有ADMIN权限的用户不能删除文章 * @param id * @param model * @return */ @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')") @GetMapping(value = "/article/{id}/deletion") public ModelAndView delete(@PathVariable("id")int id,Model model){ articleService.deleteArticle(id); model.addAttribute("articlesList",articleService.getArticles()); return new ModelAndView("article/list","articleModel",model); } }
@Controller
public class LoginController {

    @RequestMapping("/")
    public String root(){
        return "redirect:/index";
    }

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

    //@RequestMapping将接收Get,Post,Head,Options等所有的请求方式
    @RequestMapping(value = "/login")
    public String login(){
        return "login";
    }

    @RequestMapping("/loginError")
    public String loginError(ModelAndView modelAndView){
        modelAndView.addObject("loginError",true);
        return "login";
    }

    @RequestMapping("/admin")
    public String admin(){
        return "admin/admin";
    }

    //@RequestMapping(method = RequestMethod.GET)的缩写
    @GetMapping("401")
    public String error(){
        return "401";
    }
    
    @GetMapping("/logout")
    public String logout(){
        return "/";
    }
}

4.dao 层

@Repository
public interface UserDao {

    //通过用户名查询用户
    public User findUserByUsername(String username);
}

5. entity

Article

public class Article {
    private int id;
    private String title;
    private String content;
    
    public Article() {
    }

    public Article(int id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }

    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

Role

public class Role implements GrantedAuthority {

    private int id;
    private String name;

    @Override
    public String getAuthority() {
        return name;
    }

    public int getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return name;
    }
}

User

public class User implements UserDetails, Serializable {

    private int id;
    private String username;
    private String password;
    private List roles;

    @Override
    public Collection getAuthorities() {
        return roles;
    }

    @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 true;
    }
}

6.service层

@Service
public class ArticleServiceImpl implements ArticleService {

    private List
list = new ArrayList<>(); public ArticleServiceImpl() { list.add(new Article(1,"java","java从入门到搬砖")); list.add(new Article(2,"SQL","SQL从删库到跑路")); } @Override public List
getArticles() { return list; } @Override public void deleteArticle(int id) { Iterator iter = list.iterator(); while(iter.hasNext()){ Article article = (Article)iter.next(); if(article.getId()==id){ iter.remove(); } } } }
public interface ArticleService {
    List
getArticles(); void deleteArticle(int id); }
@Service
public class UserService implements UserDetailsService {
    @Autowired
    private UserDao userDao;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.err.println(userDao.findUserByUsername(username));
        return userDao.findUserByUsername(username);
    }
}

7.mapper





    
        
        
        
        
            
        
    

    
    

8.前端页面

admin.html




    
    Title


拥有权限才能访问该页面

管理文章

返回首页

list.html




    
    list


文章管理,ADMIN角色才能删除

文章编号 文章标题 文章内容
删除

index.html




    
    Title


首页任何角色都能访问

查看被保护界面: /admin

登录用户: 用户角色:

login.html




    
    Title


登录页面

用户名或密码错误

返回首页

9.数据库如下

/*
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `role`
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', 'ROLE_ADMIN');
INSERT INTO `role` VALUES ('2', 'ROLE_TEACHER');
INSERT INTO `role` VALUES ('3', 'ROLE_STUDENT');
INSERT INTO `role` VALUES ('4', 'ROLE_COUNSELOR');

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_USERNAME` (`username`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '$2a$10$NmtmORbN/ATToou17gvjl.CUu1yTNxxRjsO2GOJUbJFsWd21pYmFi');
INSERT INTO `user` VALUES ('2', 'js', '$2a$10$NmtmORbN/ATToou17gvjl.CUu1yTNxxRjsO2GOJUbJFsWd21pYmFi');
INSERT INTO `user` VALUES ('3', 'xs', '$2a$10$NmtmORbN/ATToou17gvjl.CUu1yTNxxRjsO2GOJUbJFsWd21pYmFi');
INSERT INTO `user` VALUES ('4', 'fdy', '$2a$10$NmtmORbN/ATToou17gvjl.CUu1yTNxxRjsO2GOJUbJFsWd21pYmFi');

-- ----------------------------
-- Table structure for `user_role`
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  KEY `FKuser_id` (`role_id`),
  KEY `FKrole_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1');
INSERT INTO `user_role` VALUES ('2', '2');
INSERT INTO `user_role` VALUES ('3', '3');
INSERT INTO `user_role` VALUES ('4', '4');

10.整个项目结构

SpringBoot 2.0 | Security+Mybatis 权限认证_第1张图片

3.测试结果

我们在 security 里配置了 Index 页面不需要验证即可访问,访问
http://localhost:8081/index

SpringBoot 2.0 | Security+Mybatis 权限认证_第2张图片

在没有登录之前,通过浏览器访问其他任何页面,都会跳转到登录界面。
SpringBoot 2.0 | Security+Mybatis 权限认证_第3张图片
登录之后即可进入管理页面,这里的加密密码都是123,账号请看数据库。
SpringBoot 2.0 | Security+Mybatis 权限认证_第4张图片
在管理文章里面,我们在 controller 层配置了只有 ADMIN 用户才能删除,其他用户如果点击删除将会提示没有权限。
SpringBoot 2.0 | Security+Mybatis 权限认证_第5张图片

我的 Github:Github
个人网站: 天狼星的博客
源代码:https://github.com/huangliangyun/Spring-Boot-2.X
QQ交流群:865061230
参考<<深入理解SpringCloud微服务构建>>

你可能感兴趣的:(SpringBoot,秒懂,Spring,Boot)