当前位置:   article > 正文

SpringSecurity+mybatis_spring security mybatis

spring security mybatis

SpringSecurity+thymeleaf+Mybatis+SpringBoot实现登陆功能

最近学习了SpringSecurity就写一个小小的demo来练习一下,如果帮到你了请点一个赞。

如果有错误的地方一定一定要指出来,万分感谢

1.创建一个非常简单的表

在这里插入图片描述
super代表超级管理员的一个权限。

2.引入相关的依赖(springboot的基本依赖没有写)

 		<!--springsecurity-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.4.5</version>
        </dependency>
 		<!--thymeleaf模板-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
		<!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
  		 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2.编写yml配置文件

#连接数据库
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mall?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/*.xml
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如果Mapper.xml与Mapper.class不在同一个包下或者不同名,就必须使用配置mapperLocations指定mapper.xml的位置。

3.在创建的mapper包下创建名字为AdminLoginMapper的接口

package com.taobao.mapper;

import com.taobao.pojo.Admin;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface AdminLoginMapper {
    Admin adminLogin(String admin_account);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4.编写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.taobao.mapper.AdminLoginMapper">
    <select id="adminLogin" parameterType="String" resultType="com.taobao.pojo.Admin">
        SELECT * FROM admin WHERE admin_account = #{admin_account}
    </select>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

至此关于mybatis的操作完成,本文着重与SpringSecurity就不在对mybatis做详细的讲解了。

5.在resoueces的static下引入静态资源 css js等。

在这里插入图片描述

6.在resoueces的template下创建一个login.html登录页。

<!doctype html>
<html  class="x-admin-sm" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>后台登录</title>
	<meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <link rel="stylesheet" th:href="@{/css/font.css}">
    <link rel="stylesheet" th:href="@{/css/login.css}">
	  <link rel="stylesheet" th:href="@{/css/xadmin.css}">
    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="/lib/layui/layui.js" charset="utf-8"></script>
    <!--[if lt IE 9]>
      <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
      <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body class="login-bg">
    
    <div class="login layui-anim layui-anim-up">
        <div class="message">管理登录</div>
        <div id="darkbannerwrap"></div>
        
        <form method="post" class="layui-form" th:action="@{/login}">
            <input name="username" placeholder="用户名"  type="text" lay-verify="required" class="layui-input" >
            <hr class="hr15">
            <input name="password" lay-verify="required" placeholder="密码"  type="password" class="layui-input">
            <hr class="hr15">
            <input value="登录" lay-submit lay-filter="login" style="width:100%;" type="submit">
            <hr class="hr20" >
        </form>
    </div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

这里我用的x-admin模板,不用重点关注只需要关注form表单即可。th:action=“@{}”是thymeleaf中的写法,这里也不做过多讲解。

/login下面会做解释。这里的表单提交方式必须为post,账号密码的属性值必须为uername和password下面会做解释

7.创建实体类

package com.taobao.pojo;

public class Admin {
    private Integer id;
    private String admin_account;
    private String admin_password;
    private String leavl;
    public Admin() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getAdmin_account() {
        return admin_account;
    }

    public void setAdmin_account(String admin_account) {
        this.admin_account = admin_account;
    }

    public String getAdmin_password() {
        return admin_password;
    }

    public void setAdmin_password(String admin_password) {
        this.admin_password = admin_password;
    }

    public String getLeavl() {
        return leavl;
    }

    public void setLeavl(String leavl) {
        this.leavl = leavl;
    }

    @Override
    public String toString() {
        return "Admin{" +
                "id=" + id +
                ", admin_account='" + admin_account + '\'' +
                ", admin_password='" + admin_password + '\'' +
                ", leavl='" + leavl + '\'' +
                '}';
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

8.编写SpringSecurity的配置

​ a.使用@EnableWebSecurity注解,开启Security同时说明这个Configuration类。

​ b.继承WebSecurityConfigurerAdapter这个类

​ c.重写configure(HttpSecurity http) 和 configure(HttpSecurity http) 两个方法

package com.taobao.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //下面会讲到,别急
    @Autowired
    private UserDetailsService userDetailsService;
    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {

   						http.formLogin()
   						               //自定义的登录页面,不写这个会跳到SpringSecurity自己内置的登录页面
                            .loginPage("/AdminLogin")
                            
                            .loginProcessingUrl("/user/login")
                            .defaultSuccessUrl("/admin/index").permitAll()
                            //任何请求都需要授权
                            .and().authorizeRequests()
                            .antMatchers("/","/user/login").permitAll()
                            .antMatchers("/admin/index").hasAnyAuthority("super")
                            //任何请求都不需要授权
                            .anyRequest().authenticated()
                            //关闭csrf防护
                            .and().csrf().disable();
    }
    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在数据库中获取数据,对密码进行验证,不对密码加密会报错。
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

9.创建一个service类实现UserDetailsService接口

package com.taobao.service.impl;

import com.taobao.mapper.AdminLoginMapper;
import com.taobao.pojo.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

//创建service实现UserDetailsService接口
@Service("userDetailsService")
public class AdminDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private AdminLoginMapper adminLoginMapper;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //通过用户名在数据库中查询
        Admin admin = adminLoginMapper.adminLogin(s);
        //如果admin为空说明用户名错误,抛出一个异常
        if(admin==null){
            throw new UsernameNotFoundException("用户名不存在!");
        }
        //获取该账号的权限
        List<GrantedAuthority> atuhs = AuthorityUtils.commaSeparatedStringToAuthorityList(admin.getLeavl());
        //查询数据库返回的user对象,密码认证交给security做,密码必须加密。
        return new User(admin.getAdmin_account(),new 			BCryptPasswordEncoder().encode(admin.getAdmin_password()),atuhs);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

这个类就是我们上面@Autowired的内个类

关于.loginProcessingUrl("/login")的意思登陆访问路径:提交表单之后跳转的地址,可以看作一个中转站,这个步骤就是验证user的一个过程

我的理解是 表单提交到一个controller 这个controller应该调用AdminDetailServiceImpl 。但是这个过程security已经帮我们做了,这里随便写一个地址就好了只需要和action中的保持一直

关于defaultSuccessUrl();百度了一下得到了以下的答案:(原文链接:https://www.xttblog.com/?p=4994)

其实我们通过 defaultSuccessUrl 和 successForwardUrl 的字面意思都能够理解他们的作用。

defaultSuccessUrl 有一个重载的方法,如果我们在 defaultSuccessUrl 中指定登录成功的跳转页面为 /index,此时分两种情况,如果你是直接在浏览器中输入的登录地址,登录成功后,就直接跳转到 /index,如果你是在浏览器中输入了其他地址,例如 http://localhost:8080/xttblog,结果因为没有登录,又重定向到登录页面,此时登录成功后,就不会来到 /index ,而是来到 /xttblog 页面。

defaultSuccessUrl 就是说,它会默认跳转到 Referer 来源页面,如果 Referer 为空,没有来源页,则跳转到默认设置的页面。

successForwardUrl 表示不管你是从哪里来的,登录后一律跳转到 successForwardUrl 指定的地址。例如 successForwardUrl 指定的地址为 /index ,你在浏览器地址栏输入 http://localhost:8080/codedq,如果你还没有登录,将会重定向到登录页面,当你登录成功之后,就会服务端跳转到 /index 页面;或者你直接就在浏览器输入了登录页面地址,登录成功后也是来到 /index。

defaultSuccessUrl 另外一个重载方法,第二个参数如果输入为 true,则效果和 successForwardUrl 一致。

一般来说,我们使用 defaultSuccessUrl 就够了。而且体验也比较好,特殊情况下,我们才使用 successForwardUrl。

loginPage源码的注释中已经说明,login.html 配置提交请求及方式,方式必须为post:
在这里插入图片描述

看User类的源码可以知道form表单的账号密码属性必须是username,password.

在这里插入图片描述

本人功力尚浅,道行不够。写的还不尽如人意,大家请见谅,对于错误的地方大家一定要给我指出来,我会虚心接收。谢谢

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/922027
推荐阅读
相关标签
  

闽ICP备14008679号