springboot综合案例第三课

这篇具有很好参考价值的文章主要介绍了springboot综合案例第三课。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringSecurity入门

什么是SpringSecurity

Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。

(https://projects.spring.io/spring-security/) Spring Security 为基于J2EE企业应用软件提供了全面安全服务。特别

是使用领先的J2EE解决方案-Spring框架开发的企业软件项目。人们使用Spring Security有很多种原因,不过通常吸

引他们的是在J2EE Servlet规范或EJB规范中找不到典型企业应用场景的解决方案。特别要指出的是他们不能再

WAR 或 EAR 级别进行移植。这样,如果你更换服务器环境,就要,在新的目标环境进行大量的工作,对你的应用

系统进行重新配置安全。使用Spring Security 解决了这些问题,也为你提供很多有用的,完全可以指定的其他安

全特性。安全包括两个主要操作。

  • “认证”,是为用户建立一个他所声明的主体。主题一般式指用户,设备或可以在你系统中执行动作的其他系

统。(简单来说:系统认为用户是否能登录)

  • “授权”,指的是一个用户能否在你的应用中执行某个操作,在到达授权判断之前,身份的主题已经由身份验证

过程建立了。(简单来说:系统判断用户是否有权限去做某些事情)

这些概念是通用的,不是Spring Security特有的。在身份验证层面,Spring Security广泛支持各种身份验证模式,

这些验证模型绝大多数都由第三方提供,或则正在开发的有关标准机构提供的,例如 Internet Engineering Task

Force.作为补充,Spring Security 也提供了自己的一套验证功能。

Spring Security 目前支持认证一体化如下认证技术: HTTP BASIC authentication headers (一个基于IEFT RFC 的

标准) HTTP Digest authentication headers (一个基于IEFT RFC 的标准) HTTP X.509 client certi?cate exchange

(一个基于IEFT RFC 的标准) LDAP (一个非常常见的跨平台认证需要做法,特别是在大环境) Form-based

authentication (提供简单用户接口的需求) OpenID authentication Computer Associates Siteminder JA-SIG

Central Authentication Service (CAS,这是一个流行的开源单点登录系统) Transparent authentication context

propagation for Remote Method Invocation and HttpInvoker (一个Spring远程调用协议)

用户登录认证

表结构分析与创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnUk2Dvg-1692278828416)(day03_springboot综合案例.assets/image-20210516220645141.png)]

-- 用户表
CREATE TABLE users(
	id VARCHAR(32) PRIMARY KEY,
	email VARCHAR(50) UNIQUE NOT NULL,
	username VARCHAR(50),
	PASSWORD VARCHAR(100),
	phoneNum VARCHAR(20),
	STATUS INT
);

-- 角色表
CREATE TABLE role(
    id VARCHAR(32) PRIMARY KEY,
    roleName VARCHAR(50) ,
    roleDesc VARCHAR(50)
);


-- 用户角色关联表
CREATE TABLE users_role(
    userId VARCHAR(32),
    roleId VARCHAR(32),
    PRIMARY KEY(userId,roleId),
    FOREIGN KEY (userId) REFERENCES users(id),
    FOREIGN KEY (roleId) REFERENCES role(id)
);

-- 资源权限表
CREATE TABLE permission(
    id VARCHAR(32)  PRIMARY KEY,
    permissionName VARCHAR(50) ,
    url VARCHAR(50)
);

-- 角色权限关联表
CREATE TABLE role_permission(
    permissionId VARCHAR(32),
    roleId VARCHAR(32),
    PRIMARY KEY(permissionId,roleId),
    FOREIGN KEY (permissionId) REFERENCES permission(id),
    FOREIGN KEY (roleId) REFERENCES role(id)
);

创建类

创建UserInfo


@Data
public class UserInfo {
    private String id;
    private String username;
    private String email;
    private String password;
    private String phoneNum;
    private int status;
    private String statusStr;
    
    private List<Role> roles;
}

创建Role


@Data
public class Role {
    private String id;
    private String roleName;
    private String roleDesc;
    
    private List<Permission> permissions;
    private List<UserInfo> users;
}

创建Permission


@Data
public class Permission {
    private String id;
    private String permissionName;
    private String url;
    
    private List<Role> roles;
}

Spring Security数据库认证底层

在Spring Security中如果想要使用数据进行认证操作,有很多种操作方式,这里我们介绍使用UserDetails、

UserDetailsService来完成操作。

  • UserDetails

    public interface UserDetails extends Serializable {
        Collection<? extends GrantedAuthority> getAuthorities();
    
        String getPassword();
    
        String getUsername();
    
        boolean isAccountNonExpired();
    
        boolean isAccountNonLocked();
    
        boolean isCredentialsNonExpired();
    
        boolean isEnabled();
    }
    

    UserDatails是一个接口,我们可以认为UserDetails作用是于封装当前进行认证的用户信息,但由于其是一个

    接口,所以我们可以对其进行实现,也可以使用Spring Security提供的一个UserDetails的实现类User来完成

    操作,Ctrl+Alt+B 查找接口实现类

    以下是User类的部分代码

    public class User implements UserDetails, CredentialsContainer {
        private String password;
        private final String username;
        private final Set<GrantedAuthority> authorities;
        private final boolean accountNonExpired; //帐户是否过期
        private final boolean accountNonLocked; //帐户是否锁定
        private final boolean credentialsNonExpired; //认证是否过期 
        private final boolean enabled; //帐户是否可用 
  • UserDetailsService

    public interface UserDetailsService {
        UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
    }
    

    上面将UserDetails与UserDetailsService做了一个简单的介绍,那么我们具体如何完成Spring Security的数据库认

    证操作,我们通过用户管理中用户登录来完成Spring Security的认证操作。

用户登录流程分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KG7Pu1wO-1692278828417)(assets/image-20201012180237425.png)]

登录认证

添加依赖

    <!--SpringSecurity-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

Spring Security配置类

package cn.yanqi.config;

import cn.yanqi.service.UserService;
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;
import javax.annotation.Resource;

// @EnableGlobalMethodSecurity(jsr250Enabled = true)   //开启jsr250注解
// @EnableGlobalMethodSecurity(securedEnabled = true)  //开启secured注解
// @EnableGlobalMethodSecurity(prePostEnabled = true)  //开启表达式注解
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //自定义表单登录页面
        http.formLogin()
                //指定登录页面
                .loginPage("/to/login")
                //指定登录请求
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successForwardUrl("/to/index")
                .failureUrl("/to/failer")
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/to/login")
                .invalidateHttpSession(true) //是否清除session
                .and()
                //权限配置
                .authorizeRequests()
                //放行 登录页面
                .antMatchers("/to/login","/to/failer").permitAll()
                //放开 静态资源
                .antMatchers("/css/**","/img/**","/js/**","/plugins/**").permitAll()
                //其他 资源需要登录后访问
                .anyRequest().authenticated()
                .and()
                //禁用csrf
                .csrf().disable();
        //没有权限
        http.exceptionHandling().accessDeniedPage("/to/403");
    }

    //认证的数据需要使用自定义的UserDetailsService
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

编写UserService

package cn.yanqi.service;

import org.springframework.security.core.userdetails.UserDetailsService;
//继承 UserDetailsService 重写loadUserByUsername 完成认证
public interface UserService extends UserDetailsService {
    
}

import cn.yanqi.travel.mapper.UserMapper;
import cn.yanqi.travel.pojo.Role;
import cn.yanqi.travel.pojo.UserInfo;
import cn.yanqi.travel.service.UserService;
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.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 认证--查询用户
     * @param s
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        UserInfo userInfo =  this.userMapper.findUserByUserName(s);

        User user = new User(
                userInfo.getUsername(),
                userInfo.getPassword(),
                userInfo.getStatus() == 0 ? false : true,//校验用户是否开启
                true, //帐号是否过期 不过期
                true, //证号 不过期
                true, //帐号 不锁定
                getAuthority(userInfo.getRoles()));

        System.out.println("用户:"+userInfo.getUsername());
        System.out.println("=======================");
        return user;
    }


    /**
     * 认证--查询用户对应的角色
     */
    private List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {

        List<SimpleGrantedAuthority> list = new ArrayList<>();
        for(Role role : roles){
            System.out.println("对应角色:"+role.getRoleName());
            list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }
        return list;
    }
}    

编写UserMapper

public interface UserMapper {
    /**
     * 通过用户名查询用户
     * @param s
     * @return
     */
    UserInfo findUserByUserName(String s);
}    

编写UserMapper.xml

  <!--登录认证:通过用户名查询用户-->
    <resultMap id="userresultMap" type="UserInfo" autoMapping="true">
        <id property="id" column="id"/>
        <collection property="roles"   ofType="Role" javaType="List" autoMapping="true">
            <id property="id" column="rid"/>
        </collection>
    </resultMap>
    <select id="findUserByUserName" resultMap="userresultMap">
        SELECT
        	*,r.id rid
        FROM
        	users u,
        	role r,
        	users_role ur
        WHERE
        	u.id = ur.userId 
        	AND
        	r.id = ur.roleId 
        	AND
        	u.username = #{s}
    </select>

注意事项:如果登录认证提交出现405,是因为通用页面跳转是@GetMapping, Security的登录后台跳转需要post请求

把通用页面跳转改为@RequestMapping(“{page}”)即可

测试

登录认证-把users表中的status状态修改 0和1进行测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64TQouaV-1692278828419)(day03_springboot综合案例.assets/image-20210517223706124.png)]

权限控制

Spring Security配置类

// @EnableGlobalMethodSecurity(jsr250Enabled = true)   //开启jsr250注解
// @EnableGlobalMethodSecurity(securedEnabled = true)  //开启secured注解
// @EnableGlobalMethodSecurity(prePostEnabled = true)  //开启表达式注解
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	//Spring Security配置类
}

代码实现

基于方法级别权限控制,有三种方式

    /**
     * 查询所有产品
     * @param page
     * @param size
     * @return
     */
    // @RolesAllowed({"ADMIN","USER"}) // JSR-250注解
    // @RolesAllowed("ADMIN") // JSR-250注解
    // @Secured("ROLE_ADMIN") // Secured注解
    // @PreAuthorize("authentication.principal.username == 'jack'")//只有jack才可以访问
    @RequestMapping("findAll")
    public String findAll( Model model,
            @RequestParam(value = "page",defaultValue = "1") Integer page,
            @RequestParam(value = "size",defaultValue = "5") Integer size){

        PageHelper.startPage(page,size);

        List<Product> productList =  this.productService.findAll();

        PageInfo pageInfo = new PageInfo(productList);

        model.addAttribute("pageInfo", pageInfo);
        return "product-list";
    }

uestMapping(“findAll”)
public String findAll( Model model,
@RequestParam(value = “page”,defaultValue = “1”) Integer page,
@RequestParam(value = “size”,defaultValue = “5”) Integer size){文章来源地址https://www.toymoban.com/news/detail-654697.html

    PageHelper.startPage(page,size);

    List<Product> productList =  this.productService.findAll();

    PageInfo pageInfo = new PageInfo(productList);

    model.addAttribute("pageInfo", pageInfo);
    return "product-list";
}


到了这里,关于springboot综合案例第三课的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接

    SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接

    系列文章: SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计 SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接 SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接 SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现 SpringBoot + Vue前后

    2024年02月12日
    浏览(20)
  • 【0基础学Java第三课】-- 运算符

    【0基础学Java第三课】-- 运算符

    计算机的最基本的用途之一就是执行数学运算,比如+,,就是运算符,即: 对操作数进行操作时的符号,不同运算符操作的含义不同。 作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。Java中运算符可分为以下: 算术运算符(+ - */) 关系运算符( ==) 逻辑运算符

    2024年02月07日
    浏览(12)
  • SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接

    SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接

    系列文章: SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计 SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接 SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接 SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现 SpringBoot + Vue前后

    2024年02月11日
    浏览(35)
  • 微信小程序的授权登录-Java 后端 (Spring boot)

    微信开发文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 一个可以测试的微信小程序 此微信小程序的APPID和APPscret(至开发者后台获取) 从时序图我们可以了解到流程大致分为两步: 小程序端获取code后传给Java后台 Java后台获取code后向微信后台接口

    2024年02月09日
    浏览(48)
  • “从零开始学习Spring Boot:快速搭建Java后端开发环境“

    标题:从零开始学习Spring Boot:快速搭建Java后端开发环境 摘要:本文将介绍如何从零开始学习Spring Boot,并详细讲解如何快速搭建Java后端开发环境。通过本文的指导,您将能够快速搭建一个基于Spring Boot的Java后端开发环境并开始编写代码。 正文: 一、准备工作 在开始之前,

    2024年02月15日
    浏览(15)
  • spring boot整合第三方微信开发工具 weixin-java-miniapp 实现小程序微信登录

    spring boot整合第三方微信开发工具 weixin-java-miniapp 实现小程序微信登录

    有时候项目需要用到微信登录或获取用户的手机号码,weixin-java-miniapp是一个好用的第三方工具,不用我们自己写httpcline调用。 导入jar包 添加一个resource.properties文件,写上小程序的appid和secret 添加两个配置文件 WxMaProperties.java WxMaConfiguration.java 如何使用 小程序给微信发送消息

    2024年02月16日
    浏览(49)
  • 2023 最新版IntelliJ IDEA 2023.1创建Java Web前(vue3)后端(spring-boot3)分离 项目详细步骤(图文详解)

    2023 最新版IntelliJ IDEA 2023.1创建Java Web前(vue3)后端(spring-boot3)分离 项目详细步骤(图文详解)

    2023 最新版IntelliJ IDEA 2023.1创建Java Web 项目详细步骤(图文详解) 本篇使用当前Java Web开发主流的spring-boot3框架来创建一个Java前后端分离的项目,前端使用的也是目前前端主流的vue3进行一个简单的项目搭建,让你距离Java全栈开发更近一步 🏴‍☠️。 使用版本: “17.0.1”

    2024年02月12日
    浏览(19)
  • Spring Boot 整合 Shiro(后端)

    Spring Boot 整合 Shiro(后端)

    1 Shiro 什么是 Shiro 官网: http://shiro.apache.org/ 是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、 授权、会话管理、加密等操作。 Shiro 就是用来解决安全管理的系统化框架。 2 Shiro 核心组件 用

    2024年02月09日
    浏览(18)
  • spring boot+MySQL实现班级综合测评管理系统

    spring boot+MySQL实现班级综合测评管理系统

    随着电子技术的普及和快速发展,线上管理系统被广泛的使用,有很多事业单位和商业机构都在实现电子信息化管理,班级综合测评管理也不例外,由比较传统的人工管理转向了电子化、信息化、系统化的管理。 传统的班级综合测评管理系统,一开始都是手工记录,然后将手

    2024年02月15日
    浏览(15)
  • OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt!

    OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt!

    OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt! GitHub - NiuXiangQian/chatgpt-stream: OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图

    2024年02月12日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包