Springboot详解整合SpringSecurity实现全过程

目录
  • 使用Basic认证模式
  • 使用form表形式登录
  • 实现权限控制
  • 自定义登录页面
  • 结合数据库实现RBAC权限模型权限控制
  • java代码
  • 动态绑定数据库所有权限

使用Basic认证模式

1、maven依赖

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

2、SecurityConfig 配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 添加授权账户
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.inMemoryAuthentication().withUser("kaico_admin").password("kaico")
                .authorities("/");
        // 如果kaico_admin账户权限的情况 所有的接口都可以访问,如果kaico_add 只能访问addMember
        auth.inMemoryAuthentication().withUser("kaico_add").password("kaico")
                .authorities("/");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
    }
    /**
     * There is no PasswordEncoder mapped for the id "null"
     * 原因:升级为Security5.0以上密码支持多中加密方式,恢复以前模式
     *
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

3、测试controller接口

@Controller
public class IndexController {
    /**
     * 跳转到首页
     *
     * @return
     */
    @RequestMapping("/")
    public String index() {
        return "index";
    }
    @ResponseBody
    @RequestMapping("/addMember")
    public String addMember() {
        return "新增用户";
    }
    @ResponseBody
    @RequestMapping("/delMember")
    public String delMember() {
        return "删除用户";
    }
    @ResponseBody
    @RequestMapping("/updateMember")
    public String updateMember() {
        return "修改用户";
    }
    @ResponseBody
    @RequestMapping("/showMember")
    public String showMember() {
        return "查询用户";
    }
}

使用form表形式登录

在上面Basic认证模式的基础上修改SecurityConfig配置类,修改下面的方法

@Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
    }

springSecurity默认提供登录页面,如下图所示:

注意:使用表单登录之后,登录成功之后默认跳转首页,也就是请求路径/,没有该请求路径的话会报错。

实现权限控制

上面的案例只是实现了登录认证,但是还没有实现权限控制。

在上面的基础上修改

1、修改SecurityConfig配置类

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.inMemoryAuthentication().withUser("kaico_admin").password("kaico")
                .authorities("addMember", "delMember", "updateMember", "showMember"
                );
        // 如果kaico_admin账户权限的情况 所有的接口都可以访问,如果kaico_add 只能访问addMember
        auth.inMemoryAuthentication().withUser("kaico_add").password("kaico")
                .authorities("addMember");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/**").fullyAuthenticated().and().formLogin();
    }

没有权限报403错误

修改403权限不足页面

1、增加配置类

@Configuration
public class WebServerAutoConfiguration {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
        ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
        ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
        ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
        ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
        ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
        factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
        return factory;
    }
}

2、增加对应的错误请求路径

@RestController
public class ErrorController {
    @RequestMapping("/error/403")
    public String error403(){
        return "您当前访问的接口权限不足";
    }
}

自定义登录页面

1、登录页面准备

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
</head>
<body>
<h1>权限控制登陆系统</h1>
<form action="/login" method="post">
    <span>用户名称</span><input type="text" name="username"/> <br>
    <span>用户密码</span><input type="password" name="password"/> <br>
    <input type="submit" value="登陆">

</form>
<#if RequestParameters['error']??>
    用户名称或者密码错误
</#if>
</body>
</html>

2、修改SecurityConfig配置类

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/login").permitAll() //放行登录请求页面
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();
    }

3、增加登录页面请求controller

@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(){
        return "login";
    }
}

结合数据库实现RBAC权限模型权限控制

环境准备

数据库

RBAC模型相关数据库表关系图

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(10) NOT NULL,
  `permName` varchar(50) DEFAULT NULL,
  `permTag` varchar(50) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT '请求url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '查询用户', 'showMember', '/showMember');
INSERT INTO `sys_permission` VALUES ('2', '添加用户', 'addMember', '/addMember');
INSERT INTO `sys_permission` VALUES ('3', '修改用户', 'updateMember', '/updateMember');
INSERT INTO `sys_permission` VALUES ('4', '删除用户', 'delMember', '/delMember');
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(10) NOT NULL,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'admin', '管理员');
INSERT INTO `sys_role` VALUES ('2', 'add_user', '添加管理员');
-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(10) DEFAULT NULL,
  `perm_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_3` (`role_id`),
  KEY `FK_Reference_4` (`perm_id`),
  CONSTRAINT `FK_Reference_4` FOREIGN KEY (`perm_id`) REFERENCES `sys_permission` (`id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('1', '2');
INSERT INTO `sys_role_permission` VALUES ('1', '3');
INSERT INTO `sys_role_permission` VALUES ('1', '4');
INSERT INTO `sys_role_permission` VALUES ('2', '2');
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `createDate` date DEFAULT NULL,
  `lastLoginTime` date DEFAULT NULL,
  `enabled` int(5) DEFAULT NULL,
  `accountNonExpired` int(5) DEFAULT NULL,
  `accountNonLocked` int(5) DEFAULT NULL,
  `credentialsNonExpired` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'kaico_admin', '张三', 'c2c92733a75333a4bac673632ff7519a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
INSERT INTO `sys_user` VALUES ('2', 'kaico_add', '小余', 'c2c92733a75333a4bac673632ff7519a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(10) DEFAULT NULL,
  `role_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_1` (`user_id`),
  KEY `FK_Reference_2` (`role_id`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`),
  CONSTRAINT `FK_Reference_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('1', '1');
INSERT INTO `sys_user_role` VALUES ('2', '2');

maven依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- springboot 整合mybatis框架 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- alibaba的druid数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

yml配置

# 配置freemarker
spring:
  freemarker:
    # 设置模板后缀名
    suffix: .ftl
    # 设置文档类型
    content-type: text/html
    # 设置页面编码格式
    charset: UTF-8
    # 设置页面缓存
    cache: false
    # 设置ftl文件路径
    template-loader-path:
      - classpath:/templates
  # 设置静态文件路径,js,css等
  mvc:
    static-path-pattern: /static/**
  datasource:
    name: test
    url: jdbc:mysql://www.kaicostudy.com:3306/study_springSecurity
    username: root
    password: 123456
    # druid 连接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver

java代码

实体类

// 用户信息表
@Data
public class UserEntity implements UserDetails {
	private Integer id;
	private String username;
	private String realname;
	private String password;
	private Date createDate;
	private Date lastLoginTime;
	private boolean enabled;
	private boolean accountNonExpired;
	private boolean accountNonLocked;
	private boolean credentialsNonExpired;
	// 用户所有权限
	private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}
}
// 角色信息表
@Data
public class RoleEntity {
	private Integer id;
	private String roleName;
	private String roleDesc;
}
@Data
public class PermissionEntity {
	private Integer id;
	// 权限名称
	private String permName;
	// 权限标识
	private String permTag;
	// 请求url
	private String url;
}

mapper类

@Mapper
public interface PermissionMapper {
    @Select(" select * from sys_permission ")
    List<PermissionEntity> findAllPermission();
}
@Mapper
public interface UserMapper {
    /**
     * 根据用户名称查询
     *
     * @param userName
     * @return
     */
    @Select(" select * from sys_user where username = #{userName}")
    UserEntity findByUsername(@Param("userName") String userName);
    /**
     * 查询用户的权限根据用户查询权限
     *
     * @param userName
     * @return
     */
    @Select(" select permission.* from sys_user user" + " inner join sys_user_role user_role"
            + " on user.id = user_role.user_id inner join "
            + "sys_role_permission role_permission on user_role.role_id = role_permission.role_id "
            + " inner join sys_permission permission on role_permission.perm_id = permission.id where user.username = #{userName};")
    List<PermissionEntity> findPermissionByUsername(@Param("userName") String userName);
}

实现springSecurity的接口UserDetailsService

@Component
@Slf4j
public class MemberUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    /**
     * loadUserByUserName
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.根据该用户名称查询在数据库中是否存在
        UserEntity userEntity = userMapper.findByUsername(username);
        if (userEntity == null) {
            return null;
        }
        // 2.查询对应的用户权限
        List<PermissionEntity> listPermission = userMapper.findPermissionByUsername(username);
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        listPermission.forEach(user -> {
            authorities.add(new SimpleGrantedAuthority(user.getPermTag()));
        });
        log.info(">>>authorities:{}<<<", authorities);
        // 3.将该权限添加到security
        userEntity.setAuthorities(authorities);
        return userEntity;
    }
}

密码加密工具类

public class MD5Util {
	private static final String SALT = "kaico";
	public static String encode(String password) {
		password = password + SALT;
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		char[] charArray = password.toCharArray();
		byte[] byteArray = new byte[charArray.length];
		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
}

SecurityConfig配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MemberUserDetailsService memberUserDetailsService;
    /**
     * 添加授权账户
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                //对密码做加密
                return MD5Util.encode((String) rawPassword);
            }
            /**
             *
             * @param charSequence 用户输入的密码
             * @param s 数据库字段中加密好的密码
             * @return
             */
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                String rawPass = MD5Util.encode((String) charSequence);
                boolean result = rawPass.equals(s);
                return result;
            }
        });
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/login").permitAll() //放行登录请求页面
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();
    }
}

整合完成,开始测试。

动态绑定数据库所有权限

在上面代码的基础上实现,上面是在代码中配置请求路径和权限标识的绑定,现在改成在数据库中动态配置。

SecurityConfig配置类

@Override
protected void configure(HttpSecurity http) throws Exception {
    //配置权限
    List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
            expressionInterceptUrlRegistry = http.authorizeRequests();
    allPermission.forEach((permission) -> {
        expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
                hasAnyAuthority(permission.getPermTag());
    });
    expressionInterceptUrlRegistry.antMatchers("/login").permitAll()
            .antMatchers("/**").fullyAuthenticated()
            .and().formLogin().loginPage("/login").and().csrf().disable();
}

到此这篇关于Springboot详解整合SpringSecurity实现全过程的文章就介绍到这了,更多相关Springboot SpringSecurity内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot整合springsecurity与mybatis-plus的简单实现

    1.概述 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架. 它是用于保护基于Spring的应用程序的实际标准. Spring Security是一个框架,致力于为Java应用程序提供身份验证和授权. 与所有Spring项目一样,Spring Security的真正强大之处在于可以轻松扩展以满足自定义要求 springboot对于springSecurity提供了自动化配置方案,可以使用更少的配置来使用springsecurity 而在项目开发中,主要用于对用户的

  • SpringBoot2.0 整合 SpringSecurity 框架实现用户权限安全管理方法

    一.Security简介 1.基础概念 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为安全控制编写大量重复代码的工作. 2.核心API解读 1).SecurityContextHolder 最基本的对象,保存着当前会话用户认证,权限,鉴权等核心数据.Secu

  • SpringBoot与SpringSecurity整合方法附源码

    依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Thymeleaf --> <dependency> <groupId>org.thymeleaf<

  • SpringBoot整合SpringSecurity实现权限控制之实现多标签页

    目录 一.需求描述 二.前端实现 三.效果演示 四.源码 一.需求描述 多标签页 (Tabs) 的设计对于多窗口多任务管理有着无与伦比的高效率与方便性 在上面的文章中已经实现了后台管理的基本权限功能,包括用户.角色.菜单管理及权限分配. 用户通过单击侧边栏的菜单,就可以调出对应的功能页面进行使用.但在使用的过程中,我们发现程序只能在同一时间打开一个页面.我们更希望打开多个功能页面时,这些页面以标签的形式集成在同一个窗口显示,要想切换到某个页面或是关闭某个页面,我们只需要操作相应的标签即可,非常方

  • 详解SpringBoot+SpringSecurity+jwt整合及初体验

    原来一直使用shiro做安全框架,配置起来相当方便,正好有机会接触下SpringSecurity,学习下这个.顺道结合下jwt,把安全信息管理的问题扔给客户端, 准备 首先用的是SpringBoot,省去写各种xml的时间.然后把依赖加入一下 <!--安全--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-secu

  • SpringBoot如何整合Springsecurity实现数据库登录及权限控制

    目录 第一步 第二步是封装一个自定义的类 第三步, 我们需要判断密码啦 总结 我们今天使用SpringBoot来整合SpringSecurity,来吧,不多BB 首先呢,是一个SpringBoot 项目,连接数据库,这里我使用的是mybaties.mysql, 下面是数据库的表 DROP TABLE IF EXISTS `xy_role`; CREATE TABLE `xy_role` ( `xyr_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键i

  • SpringBoot整合SpringSecurityOauth2实现鉴权动态权限问题

    目录 写在前面 准备 效果展示 实现 写在前面 思考:为什么需要鉴权呢? 系统开发好上线后,API接口会暴露在互联网上会存在一定的安全风险,例如:爬虫.恶意访问等.因此,我们需要对非开放API接口进行用户鉴权,鉴权通过之后再允许调用. 准备 spring-boot:2.1.4.RELEASE spring-security-oauth2:2.3.3.RELEASE(如果要使用源码,不要随意改动这个版本号,因为2.4往上的写法不一样了) mysql:5.7 效果展示 这边只用了postman做测试

  • Springboot安全框架整合SpringSecurity实现方式

    目录 1.工业级安全框架介绍 2.建议搭建Spring Security环境 2.1在pom.xml中添加相关依赖 2.2创建Handler类 2.3创建简单的html和配置相关thymeleaf的路径 2.4最后再加个启动类,那么我们的整合测试就完成勒 2.5成果展示 用户名默认user,密码则随机生成的这串数字 3.进阶版使用 3.1用户名和密码自定义 3.2在config包下创建Encoder进行密码的校验和转码操作 3.3赋予账号角色权限 1.工业级安全框架介绍 Spring Secur

  • SpringSecurity整合springBoot、redis实现登录互踢功能

    背景 基于我的文章--<SpringSecurity整合springBoot.redis token动态url权限校验>.要实现的功能是要实现一个用户不可以同时在两台设备上登录,有两种思路: (1)后来的登录自动踢掉前面的登录. (2)如果用户已经登录,则不允许后来者登录. 需要特别说明的是,项目的基础是已经是redis维护的session. 配置redisHttpSession 设置spring session由redis 管理. 2.1去掉yml中的http session 配置,yml和

  • Springboot详解整合SpringSecurity实现全过程

    目录 使用Basic认证模式 使用form表形式登录 实现权限控制 自定义登录页面 结合数据库实现RBAC权限模型权限控制 java代码 动态绑定数据库所有权限 使用Basic认证模式 1.maven依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.

  • SpringBoot详解整合MyBatis过程中可能遇到的问题

    尽量不要用 jUnit 提供的单元测试 提一个要求尽量使用SpringBoot 提供的测试类进行测试,能够自动扫描组件以及使用容器中的bean对象 还有如果有组件 中存在注入对象的话,那么必须在SpringBoot容器中取出 这个组件,进而使用注入的对象的功能!!! 今天有个错误,花了很长时间来解决,最后发现是一个很低级很基础的错误! 这是mapper接口,使用@mapper 相当于将接口的代理对象注册进入bean中,但是上下文中找不到(其实是正常) 因为 @Mapper 这个注解是 Mybat

  • springboot详解整合swagger方案

    目录 1.Swagger简介 2.整合步骤 1.Swagger简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 官网: ( https://swagger.io/ ) 主要作用是: 1. 使得前后端分离开发更加方便,有利于团队协作 2. 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担 3. 功能测试 Spring已经将Swagger纳入自身的标准,建立了Spring-swagger项目,现在叫 Springfox.通过

  • SpringBoot详解整合Spring Boot Admin实现监控功能

    目录 监控 监控的意义 可视化监控平台 监控原理 自定义监控指标 监控 ​ 在说监控之前,需要回顾一下软件业的发展史.最早的软件完成一些非常简单的功能,代码不多,错误也少.随着软件功能的逐步完善,软件的功能变得越来越复杂,功能不能得到有效的保障,这个阶段出现了针对软件功能的检测,也就是软件测试.伴随着计算机操作系统的逐步升级,软件的运行状态也变得开始让人捉摸不透,出现了不稳定的状况.伴随着计算机网络的发展,程序也从单机状态切换成基于计算机网络的程序,应用于网络的程序开始出现,由于网络的不稳定性,

  • SpringBoot详解整合Redis缓存方法

    目录 1.Spring Boot支持的缓存组件 2.基于注解的Redis缓存实现 3.基于API的Redis缓存实现 1.Spring Boot支持的缓存组件 在Spring Boot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口. 如果程序中没有定义类型为CacheManager的Bean组件或者是名为cacheResolve

  • SpringBoot详解整合Spring Cache实现Redis缓存流程

    目录 1.简介 2.常用注解 2.1.@EnableCaching 2.2.@Cacheable 2.3.@CachePut 2.4.@CacheEvict 3.使用Redis当作缓存产品 3.1.坐标导入 3.2.yml配置 3.3.开启注解功能 3.4.使用@Cacheable 3.5.使用@CacheEvict 4.测试 1.简介 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能. Spring Cache 提供了一层抽象,底层可以切

  • SpringBoot详解如何进行整合Druid数据源

    目录 1.自定义方式 1.添加依赖 2.编写配置 3.测试 2.starter方式(推荐) 1.添加依赖 2.编写配置 3.测试 Druid是数据库连接池,它能够提供强大的监控和扩展功能.官方文档 Spring Boot整合第三方技术的两种方式: 自定义 找starter场景 1.自定义方式 使用自定义方式整合Druid 1.添加依赖 在pom.xml添加相关依赖 <!--数据库相关--> <dependency> <groupId>org.springframewor

  • Springboot详解如何整合使用Thymeleaf

    目录 引入Thymeleaf 取值 有无转义 循环 模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式.而这些值,从哪来呢,就是我们在后台封装一些数据.然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析.填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎 如果我们没有模板引擎的话,在页面中会提示500 引入Thymeleaf 在项目中加入依赖 <!--thymeleaf--> <

  • SpringBoot详解如何整合Redis缓存验证码

    目录 1.简介 2.介绍 3.前期配置 3.1.坐标导入 3.2.配置文件 3.3.配置类 4.Java操作Redis 1.简介 Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. 翻译:Redis 是一个开源的内存中的数据结构存储系统,它可以用作:数据库.缓存和消息中间件. 官网链接:https://redis

  • Springboot详解RocketMQ实现广播消息流程

    RocketMQ消息模式主要有两种:广播模式.集群模式(负载均衡模式) 广播模式是每个消费者,都会消费消息: 负载均衡模式是每一个消费只会被某一个消费者消费一次: 我们业务上一般用的是负载均衡模式,当然一些特殊场景需要用到广播模式,比如发送一个信息到邮箱,手机,站内提示: 我们可以通过@RocketMQMessageListener的messageModel属性值来设置,MessageModel.BROADCASTING是广播模式,MessageModel.CLUSTERING是默认集群负载均衡

随机推荐