springsecurity轻松实现角色权限的示例代码

问题:

如何在springboot项目中使用springsecurity去实现角色权限管理呢?本文将尽可能简单的一步步实现对接口的角色权限管理。

项目框架:

sql:

user表:

CREATE TABLE `user` (
 `Id` int NOT NULL AUTO_INCREMENT,
 `UserName` varchar(255) NOT NULL,
 `CreatedDT` datetime DEFAULT NULL,
 `Age` int DEFAULT NULL,
 `Gender` int DEFAULT NULL,
 `Password` varchar(255) NOT NULL,
 PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

role表:

CREATE TABLE `role` (
 `Id` int NOT NULL AUTO_INCREMENT,
 `UserId` int DEFAULT NULL,
 `Role` varchar(255) DEFAULT NULL,
 `CreatedDT` datetime DEFAULT NULL,
 PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

maven:

在pom.xml中加入

   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <!--SpringSecurity依赖配置-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!--Hutool Java工具包-->
    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>4.5.7</version>
    </dependency>

model:

实体类User要实现springsecurity的基本接口UserDetails,UserDetails里继承了Serializable,不用担心序列化

@Data
public class User implements UserDetails {
​
 public User() {
 }
​
 private static final long serialVersionUID = 1L; 

 private Integer id;
​
 private String userName;
​
 private Date createdDT;
​
 private Integer age;
​
 private Integer gender;
​
 private String passWord;
​
 private String role;
​
 private List<GrantedAuthority> authorities;
​
 public User(String userName, String passWord, List<GrantedAuthority> authorities) {
 this.userName = userName;
 this.passWord = passWord;
 this.authorities = authorities;
 }
​
 @Override
 public Collection<? extends GrantedAuthority> getAuthorities() {
 return authorities;
 }
​
 @Override
 public String getPassword() {
 return this.passWord;
 }
​
 @Override
 public String getUsername() {
 return this.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;
 }
} 

实体类role:

@Data
public class Role implements Serializable {
 private Integer id;
​
 private String role;
​
 private Date createdDT;
​
 private Integer userId;
} 

mapper:

@Mapper
public interface UserMapper{
 User selectOneByName(User user);
}

service:

public interface UserService{
 User selectOneByName(User user) throws ServiceException;
}

serviceImpl:

@Service
public class UserServiceImpl implements UserService {
 @Autowired
 private UserMapper mapper;
​
 @Override
 public User selectOneByName(User user) throws ServiceException {
 return mapper.selectOneByName(user);
 }
}

mapper.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="com.pzh.hyh.demo.mapper.UserMapper"><!--  mapper相对路径-->
 <resultMap id="BaseResultMap" type="com.pzh.hyh.demo.model.User"><!--  model相对路径-->
 <result column="Id" jdbcType="INTEGER" property="id"/>
 <result column="UserName" jdbcType="VARCHAR" property="userName"/>
 <result column="CreatedDT" jdbcType="TIMESTAMP" propert="createdDT"/>
 <result column="Age" jdbcType="INTEGER" property="age"/>
 <result column="Gender" jdbcType="INTEGER" property="gender"/>
 <result column="Password" jdbcType="VARCHAR" property="passWord"/>
 </resultMap>
​
 <sql id="Base_Column_List">
 Id, UserName, CreatedDT, Age, Gender,Password
 </sql> 

 <select id="selectOneByName" parameterType="com.pzh.hyh.demo.model.User" resultMap="BaseResultMap"><!--  model相对路径-->
 SELECT u.*,r.role FROM `user` u LEFT JOIN role r on u.Id = r.UserId
 where u.UserName = #{userName,jdbcType=VARCHAR}
 </select>
​
</mapper> 

config:

首先实现UserDetailsService类。自定义获取用户信息和角色信息。

@Component
public class CustomUserDetailsService implements UserDetailsService {
 @Autowired
 private UserService userService;
​
 @Autowired
 private HttpServletRequest request;
​
 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 // 通过用户名从数据库获取用户信息
 User user = userService.selectOneByName(new User(){
 {
 setUserName(username);
 }
 });
 if (user == null) {
 throw new UsernameNotFoundException("用户不存在");
 }
​
 HttpSession session = request.getSession();
 session.setAttribute(session.getId(),user);
​
 // 得到用户角色
 String role = user.getRole();
​
 // 角色集合
 List<GrantedAuthority> authorities = new ArrayList<>();
 // 角色必须以`ROLE_`开头,数据库中没有,则在这里加
 authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
​
 return new User(
 user.getUsername(),
 user.getPassword(),
 authorities
 );
 }
}

自定义错误提示

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
 @Override
 public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
 response.setCharacterEncoding("UTF-8");
 response.setContentType("application/json");
 response.getWriter().println("{'code':'403','message':'没有访问权限'}");
 response.getWriter().flush();
 }
}

终于来到security的配置了

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 @Autowired
 private CustomUserDetailsService userDatailService;
​
 @Autowired
 private MyAccessDeniedHandler accessDeniedHandler;
​
 @Bean
 public PasswordEncoder passwordEncoder(){
 return new BCryptPasswordEncoder();
 }
​
 @Override
 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 auth
 .userDetailsService(userDatailService)
 .passwordEncoder(passwordEncoder());
 }
​
​
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http
 .headers().frameOptions().disable()
 .and()
 .authorizeRequests()
 .antMatchers("不限制访问的路径,如:'/user/*'").permitAll()
 .antMatchers("用户拥有规定角色才允许访问的路径,如:'/user/delte'").hasRole("admin")
 .antMatchers("规定ip才允许访问的路径,如:'/*'").hasIpAddress("192.168.1.1/24");
 .anyRequest().authenticated() // 所有请求都需要验证
 .and()
 // 跳转自定义成功页
 .formLogin().defaultSuccessUrl("/html/index.html")
 .and()
 .exceptionHandling()
 //用户无权限访问链接,给出友好提示
 .accessDeniedHandler(accessDeniedHandler)
 .and()
 .csrf().disable();// post请求要关闭csrf验证,不然访问报错;实际开发中要开启。
 }
}

至此,springsecurity的角色权限管理就完成了,如果想要实现方法级的角色权限限制,可以在方法前加入 @PreAuthorize("hasRole('角色')")注解,多个角色可以使用hasAnyRole(),就可以限制拥有规定角色权限的用户才能访问了。

 @PreAuthorize("hasRole('admin')")
 @RequestMapping(value = "/delete")
 public CommonResult delete(@RequestBody int id) {
   int i = userService.delete(new User() {
   {
    setId(id);
   }
   });
   return i > 0 ? processSuccess("删除成功") : processFailure("删除失败");
 }

到此这篇关于springsecurity轻松实现角色权限的示例代码的文章就介绍到这了,更多相关springsecurity 角色权限内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringSecurity动态加载用户角色权限实现登录及鉴权功能

    很多人觉得Spring Security实现登录验证很难,我最开始学习的时候也这样觉得.因为我好久都没看懂我该怎么样将自己写的用于接收用户名密码的Controller与Spring Security结合使用,这是一个先入为主的误区.后来我搞懂了:根本不用你自己去写Controller. 你只需要告诉Spring Security用户信息.角色信息.权限信息.登录页是什么?登陆成功页是什么?或者其他有关登录的一切信息.具体的登录验证逻辑它来帮你实现. 一.动态数据登录验证的基础知识 在本号之前的文

  • springsecurity轻松实现角色权限的示例代码

    问题: 如何在springboot项目中使用springsecurity去实现角色权限管理呢?本文将尽可能简单的一步步实现对接口的角色权限管理. 项目框架: sql: user表: CREATE TABLE `user` ( `Id` int NOT NULL AUTO_INCREMENT, `UserName` varchar(255) NOT NULL, `CreatedDT` datetime DEFAULT NULL, `Age` int DEFAULT NULL, `Gender` i

  • Mybatis拦截器实现数据权限的示例代码

    在我们日常开发过程中,通常会涉及到数据权限问题,下面以我们常见的一种场景举例: 一个公司有很多部门,每个人所处的部门和角色也不同,所以数据权限也可能不同,比如超级管理员可以查看某张 表的素有信息,部门领导可以查看该部门下的相关信息,部门普通人员只可以查看个人相关信息,而且由于角色的 不同,各个角色所能查看到的数据库字段也可能不相同,那么此处就涉及到了数据权限相关的问题.那么我们该如 何处理数据权限相关的问题呢?我们提供一种通过Mybatis拦截器实现的方式,下面我们来具体实现一下 pom.xml

  • windows10 pycharm下安装pyltp库和加载模型实现语义角色标注的示例代码

    最近在上<自然语言处理>这门选修课,为了完成上机作业也是很认真了,这次是为了实现语角色标注任务,于是就入了这个坑,让我们来(快乐地 )解决出现的问题. 问题一:下载安装pyltp实现语义角色标注是在python3.6环境下实现的,(别问我怎么知道的,自己安装失败n次,问了室友才知道的 ),如果你的pycharm解释器安装的是3.7的该咋办呢? 答:再下载一个Python3.6在电脑的环境变量里把3.6的放到3.7的前面,这样就可以了,具体实施如下: 1.去Python官网下一个3.6版本的应用

  • SpringSecurity自定义成功失败处理器的示例代码

    1. 新建SpringBoot工程 2. 项目依赖 <dependencies> <!-- security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- thymeleaf -->

  • vue轻松实现虚拟滚动的示例代码

    目录 前言 滚动原理 实现 源代码 参考 前言 移动端网页的日常开发中,偶尔会包含一些渲染长列表的场景.比如某旅游网站需要完全展示出全国的城市列表,再有将所有通讯录的姓名按照A,B,C...首字母依次排序展示. 长列表的数量一般在几百条范围内不会出现意外的效果,浏览器本身足以支撑.可一旦数量级达到上千,页面渲染过程会出现明显的卡顿.数量突破上万甚至十几万时,网页可能直接崩溃了. 为了解决长列表造成的渲染压力,业界出现了相应的应对技术,即长列表的虚拟滚动. 虚拟滚动的本质,不管页面如何滑动,HTM

  • laravel实现简单用户权限的示例代码

    关于权限管理的思考 最近用laravel设计后台,后台需要有个权限管理.权限管理实质上分为两个部分,首先是认证,然后是权限.认证部分非常好做,就是管理员登录,记录session.这个laravel中也有自带Auth来实现这个.最麻烦就是权限认证. 权限认证本质上就是谁有权限管理什么东西.这里有两个方面的维度,谁,就是用户维度,在用户维度,权限管理的粒度可以是用户一个人,也可以是将用户分组,如果将用户分组,则涉及到的逻辑是一个用户可以在多个组里面吗?在另外一方面,管理什么东西,这个东西是物的维度,

  • Springboot+SpringSecurity+JWT实现用户登录和权限认证示例

    如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的后端框架是Spring-Security,该框架提供了一整套比较成熟,也很完整的机制用于处理各类场景下的可以基于权限,资源路径,以及授权方面的解决方案,部分模块支持定制化,而且在和oauth2.0进行了很好的无缝连接,在移动互联网的授权认证方面有很强的优势,具体的使用大家可以结合自己的业务场景进行选

  • SpringBoot中整合Shiro实现权限管理的示例代码

    之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧 一.简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序. 三个核心组件: 1.Subject 即"当前操作用户".但是,在 Shi

  • Springboot+Spring Security实现前后端分离登录认证及权限控制的示例代码

    目录 前言 本文主要的功能 一.准备工作 1.统一错误码枚举 2.统一json返回体 3.返回体构造工具 4.pom 5.配置文件 二.数据库表设计 初始化表数据语句 三.Spring Security核心配置:WebSecurityConfig 四.用户登录认证逻辑:UserDetailsService 1.创建自定义UserDetailsService 2.准备service和dao层方法 五.用户密码加密 六.屏蔽Spring Security默认重定向登录页面以实现前后端分离功能 1.实

  • Spring Security实现统一登录与权限控制的示例代码

    目录 项目介绍 统一认证中心 配置授权服务器 配置WebSecurity 登录 菜单 鉴权 资源访问的一些配置 有用的文档 项目介绍 最开始是一个单体应用,所有功能模块都写在一个项目里,后来觉得项目越来越大,于是决定把一些功能拆分出去,形成一个一个独立的微服务,于是就有个问题了,登录.退出.权限控制这些东西怎么办呢?总不能每个服务都复制一套吧,最好的方式是将认证与鉴权也单独抽离出来作为公共的服务,业务系统只专心做业务接口开发即可,完全不用理会权限这些与之不相关的东西了.于是,便有了下面的架构图:

随机推荐