博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot 2.0 | Security+Mybatis 权限认证
阅读量:4104 次
发布时间:2019-05-25

本文共 10163 字,大约阅读时间需要 33 分钟。

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# 集成Mybatismybatis:  # 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 层

@Controllerpublic 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); }}
@Controllerpublic 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 层

@Repositorypublic 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层

@Servicepublic 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);}
@Servicepublic 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.整个项目结构

在这里插入图片描述

3.测试结果

我们在 security 里配置了 Index 页面不需要验证即可访问,访问

http://localhost:8081/index

在这里插入图片描述

在没有登录之前,通过浏览器访问其他任何页面,都会跳转到登录界面。

在这里插入图片描述
登录之后即可进入管理页面,这里的加密密码都是123,账号请看数据库。
在这里插入图片描述
在管理文章里面,我们在 controller 层配置了只有 ADMIN 用户才能删除,其他用户如果点击删除将会提示没有权限。
在这里插入图片描述

公众号:【星尘Pro】

github:

推荐阅读

转载地址:http://gbfsi.baihongyu.com/

你可能感兴趣的文章
C++静态成员函数访问非静态成员的几种方法
查看>>
类中的静态成员函数访问非静态成员变量
查看>>
C++学习之普通函数指针与成员函数指针
查看>>
C++的静态成员函数指针
查看>>
Linux系统编程——线程池
查看>>
yfan.qiu linux硬链接与软链接
查看>>
Linux C++线程池实例
查看>>
shared_ptr简介以及常见问题
查看>>
c++11 你需要知道这些就够了
查看>>
c++11 你需要知道这些就够了
查看>>
shared_ptr的一些尴尬
查看>>
C++总结8——shared_ptr和weak_ptr智能指针
查看>>
c++写时拷贝1
查看>>
C++ 写时拷贝 2
查看>>
Linux网络编程---I/O复用模型之poll
查看>>
Java NIO详解
查看>>
单列模式-编写类ConfigManager读取属性文件
查看>>
java中float和double的区别
查看>>
Statement与PreparedStatement区别
查看>>
Tomcat配置数据源步骤以及使用JNDI
查看>>