基于MyBatis的Spring Boot Security的操作实例

目录
1、创建Spring Boot Web应用
2、修改pom.xml文件
3、设置上下文路径和数据源配置信息
4、整理脚本样式静态文件
5、创建用户和权限持久化实体类
6、创建数据访问层接口
7、创建Mapper映射文件
8、创建业务层
9、创建控制器类
10、创建应用的安全控制相关实现
11、创建用于测试的视图页面
12、修改Application类
13、测试应用
14、附数据库脚本

 

 

详细过程:

1、创建Spring Boot Web应用

 

 

 

2、修改pom.xml文件

添加mysql连接器
完整POM文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mm</groupId>
    <artifactId>security_mybatis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>security_mybatis</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

 

3、设置上下文路径和数据源配置信息

0
server.servlet.context-path=/sm
##数据源信息配置
spring.datasource.url=jdbc:mysql://localhost:3306/springtest?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=test.1234
#数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置包别名(在Mapper映射文件中直接使用实体类名)
mybatis.type-aliases-package=com.mm.security_mybatis.entity
#告诉系统到哪里去找mapper.xml文件(映射文件)
mybatis.mapper-locations=classpath:mappers/*.xml
#在控制台输出SQL语句日志
logging.level.com.mm.security_mybatis.repository=debug
logging.level.org.springframework.security=trace
spring.jackson.serialization.indent-output=true
spring.thymeleaf.cache=false
#放开不允许循环依赖的要求
spring.main.allow-circular-references=true

 

4、整理脚本样式静态文件

 

5、创建用户和权限持久化实体类

创建包:entity,并在该包中创建持久化实体类MyUser和Authrity。

MyUser:保存用户数据,用户名唯一。

Authrity:保存权限信息。

用户和权限是多对多关系。

package com.mm.security_mybatis.entity;

import java.io.Serializable;
import java.util.List;

public class MyUser implements Serializable {
    private static final long serialVersionUID=1L;
    private int id;
    private String username;
    private String password;
    private String repassword;
    private List<Authority> authorityList;
    //省略set和get方法
}

 

package com.mm.security_mybatis.entity;

import java.io.Serializable;
import java.util.List;

public class Authority implements Serializable {
    private static final long serialVersionUID=1L;
    private int id;
    private String name;
    private List<MyUser> userList;
    //省略set和get方法
}

 

6、创建数据访问层接口

创建包:repository,并在该包中创建接口:MyUserRepository。具体代码如下:
package com.mm.security_mybatis.repository;

import com.mm.security_mybatis.entity.Authority;
import com.mm.security_mybatis.entity.MyUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface MyUserRepository {
    /**
     * 根据用户名查询用户信息
     * @param username
     * @return
     */
    MyUser findByUsername(String username);

    /**
     * 根据用户ID查询用户的权限列表
     * @param id
     * @return
     */
    List<Authority> findRoleByUser(Integer id);

    /**
     * 注册用户
     * @param myUser
     * @return
     */
    int save(MyUser myUser);

    /**
     * 保存用户权限
     * @param user_id
     * @param authority_id
     * @return
     */
    int saveUserAuthority(@Param("user_id") Integer user_id,@Param("authority_id") Integer authority_id);
}

 

7、创建Mapper映射文件

在src/main/resource目录下,创建名为mappers的包,并在该包中创建SQL映射文件MyUserMapper.xml。

 

 

 //@Repository

具体代码如下:

<?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.mm.security_mybatis.repository.MyUserRepository" >
    <!-- 根据用户名级联查询用户权限 -->
    <resultMap id="myResult" type="MyUser">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="authorityList" ofType="authority"
                    column="id"
                    fetchType="eager"
                    select="com.mm.security_mybatis.repository.MyUserRepository.findRoleByUser"/>
    </resultMap>
    <!-- 根据用户名查询用户信息 -->
    <select id="findByUsername" parameterType="string" resultMap="myResult">
        select  * from user where username=#{username}
    </select>

    <!-- 根据用户ID查询用户的权限列表 -->
    <select id="findRoleByUser" parameterType="integer" resultType="Authority">
        select  id,name from authority a,user_authority ua where a.id=ua.authority_id and ua.user_id=#{id}
    </select>

    <!-- 注册用户,并将主键保存到MyUser对象的ID属性中 -->
    <insert id="save" parameterType="MyUser" keyProperty="id" useGeneratedKeys="true">
        insert into user(id,username,password) values (null,#{username},#{password})
    </insert>

    <!-- 添加用户权限 -->
    <insert id="saveUserAuthority">
        insert into user_authority(user_id,authority_id) values (#{user_id},#{authority_id})
    </insert>
</mapper>
View Code

 

 

8、创建业务层

创建包:service。在该包中创建UserService接口和UserServiceImpl实现类。

UserService代码如下:

package com.mm.security_mybatis.service;

import com.mm.security_mybatis.entity.MyUser;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface UserService {
    public String register(MyUser userDomain);
    public String loginSuccess(Model model);
    public String main(Model model);
    public String deniedAccess(Model model);
    public String logout(HttpServletRequest request, HttpServletResponse response);

}
View Code

 

UserServiceImpl代码如下:

package com.mm.security_mybatis.service;

import com.mm.security_mybatis.entity.MyUser;
import com.mm.security_mybatis.repository.MyUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private MyUserRepository myUserRepository;

    @Override
    public String register(MyUser userDomain) {
        String username=userDomain.getUsername();
        //加密密码
        String secret=new BCryptPasswordEncoder().encode(userDomain.getPassword());
        userDomain.setPassword(secret);
        int n=myUserRepository.save(userDomain);
        //管理员权限
        if("admin".equals(username)){
            myUserRepository.saveUserAuthority(userDomain.getId(),1);
            myUserRepository.saveUserAuthority(userDomain.getId(),2);
        }
        else {
            myUserRepository.saveUserAuthority(userDomain.getId(),3);
        }
        if(n!=0){
            return "/login";
        }else {
            return "/register";
        }
    }

    /**
     * 用户登录成功
     * @param model
     * @return
     */
    @Override
    public String loginSuccess(Model model) {
        model.addAttribute("user",getUname());
        model.addAttribute("role",getAuthorities());
        return "/user/loginSuccess";
    }

    /**
     * 管理员登录成功
     * @param model
     * @return
     */
    @Override
    public String main(Model model) {
        model.addAttribute("user",getUname());
        model.addAttribute("role",getAuthorities());
        return "/admin/main";
    }

    /**
     * 没有权限访问
     * @param model
     * @return
     */
    @Override
    public String deniedAccess(Model model) {
        model.addAttribute("user",getUname());
        model.addAttribute("role",getAuthorities());
        return "/deniedAccess";
    }
    /**
     * 注销用户
     * @param request
     * @param response
     * @return
     */
    @Override
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
        if(authentication!=null){
            new SecurityContextLogoutHandler().logout(request,response,authentication);
        }
        return "redirect:/login?logout";
    }

    /**
     * 获取当前用户名称
     * @return
     */
    private String getUname(){
        return SecurityContextHolder.getContext().getAuthentication().getName();
    }

    /**
     * 获取当前用户权限
     * @return
     */
    private String getAuthorities(){
        Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
        List<String> roles=new ArrayList<>();
        for(GrantedAuthority ga :authentication.getAuthorities()){
            roles.add(ga.getAuthority());
        }
        return roles.toString();
    }
}
View Code

 

9、创建控制器类

创建包:controller。在该包中创建控制器类TestSecurityController。具体代码如下。

package com.mm.security_mybatis.controller;

import com.mm.security_mybatis.entity.MyUser;
import com.mm.security_mybatis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class TestSecurityController {
    @Autowired
    private UserService userService;

    @RequestMapping("/")
    public String index(){
        return "/index";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "/login";
    }

    @RequestMapping("/toRegister")
    public String toRegister(@ModelAttribute("userDomain") MyUser userDomain){
        return "/register";
    }

    @RequestMapping("/register")
    public String register(@ModelAttribute("userDomain") MyUser userDomain){
        return userService.register(userDomain);
    }

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

    @RequestMapping("/user/loginSuccess")
    public String loginSuccess(Model model){
        return userService.loginSuccess(model);
    }

    @RequestMapping("/admin/main")
    public String main(Model model){
        return userService.main(model);
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response){
        return  userService.logout(request, response);
    }

    @RequestMapping("/deniedAccess")
    public String deniedAccess(Model model){
        return userService.deniedAccess(model);
    }
}
View Code

 

10、创建应用的安全控制相关实现

创建包:security。在该包中创建MyUserSecurityService、MyAuthenticationSuccessHandler、MySecurityConfigurerAdapter类。

MyUserSecurityService实现了UserDetailsService接口,并通过重写loadUserByUsername(String username)方法查询对应的用户,并将用户名、密码、权限等认证相关的信息封装在UserDetails对象中。

MyUserSecurityService具体代码如下:

package com.mm.security_mybatis.security;

import com.mm.security_mybatis.entity.Authority;
import com.mm.security_mybatis.entity.MyUser;
import com.mm.security_mybatis.repository.MyUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MyUserSecurityService implements UserDetailsService {
    //@Autowired(required = false)
    @Autowired
    private MyUserRepository myUserRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        MyUser myUser=myUserRepository.findByUsername(username);
        if(myUser==null){
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<GrantedAuthority> authorities=new ArrayList<>();
        List<Authority> rules=myUser.getAuthorityList();

        for(Authority authority :rules){
            GrantedAuthority sg=new SimpleGrantedAuthority(authority.getName());
            authorities.add(sg);
        }
        User su=new User(myUser.getUsername(),myUser.getPassword(),authorities);
        return su;
    }
}
View Code

 

注意:如果注入数据层有红色下划线,并提示“Could not autowire. No beans of 'MyUserRepository' type found. ”,

如下报错:

 解决方案一:可在数据层商加注解@Repository。

 解决方案二:使用注解:@Autowired(required = false)

MyAuthenticationSuccessHandler继承了SimpleUrlAuthenticationSuccessHandler类,并重写了handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)方法,根据当前认证用户的角色指定对应的URL。
MyAuthenticationSuccessHandler具体代码如下:
package com.mm.security_mybatis.security;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Component
public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    private RedirectStrategy redirectStrategy=new DefaultRedirectStrategy();

    @Override
    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String tagerUrl=getTargetUrl(authentication);
        redirectStrategy.sendRedirect(request,response,tagerUrl);
        //super.handle(request, response, authentication);
    }


    protected String getTargetUrl(Authentication authentication){
        String url="";
        Collection<? extends GrantedAuthority> authorities=authentication.getAuthorities();
        List<String> roles=new ArrayList<>();
        for(GrantedAuthority au : authorities){
            roles.add(au.getAuthority());
        }
        if(roles.contains("ROLE_USER")){
            url="/user/loginSuccess";
            //      url="/loginSuccess";
        } else if(roles.contains("ROLE_ADMIN")){
            url="/admin/main";
            //      url="/main";
        }else{
            url="/deniedAccess";
        }
        return url;
    }
}
View Code

 

MySecurityConfigurerAdapter 类继承了WebSecurityConfigurerAdapter类,并通过重写configure(AuthenticationManagerBuilder auth) 方法实现了用户认证,重写 configure(HttpSecurity http)方法实现用户授权操作。
MySecurityConfigurerAdapter具体代码如下:
package com.mm.security_mybatis.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class MySecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserSecurityService myUserSecurityService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationProvider authenticationProvider;

    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

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

    @Bean
    public AuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider provider=new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(myUserSecurityService);
        provider.setPasswordEncoder(passwordEncoder);
        return provider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        System.out.println("configure(AuthenticationManagerBuilder auth)");
        auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        System.out.println(" configure(HttpSecurity http)");
        http.authorizeRequests()
                .antMatchers("/toLogin","/toRegister","/","/login","/register","/css/**","/fonts/**","/js/**").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasAnyRole("ADMIN","DBA")
//                .antMatchers("/loginSuccess").hasRole("USER")
//                .antMatchers("/main").hasAnyRole("ADMIN","DBA")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login").successHandler(myAuthenticationSuccessHandler)
                .usernameParameter("username").passwordParameter("password")
                .failureForwardUrl("/login?error")
                .and()
                .logout().permitAll()
                .and()
                .exceptionHandling().accessDeniedPage("/deniedAccess");
    }

}
View Code

 

 

11、创建用于测试的视图页面

在src/main/resources/templates目录下创建应用的首页、注册、登录以及拒绝访问页面;
在src/main/resources/templates/admin目录下创建应用的管理员用户认证成功后访问的页面;
在src/main/resources/templates/user目录下创建应用的普通用户认证成功后访问的页面。

首页index.html的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">Spring Security 测试首页</h3>
    </div>
</div>
<div class="container">
    <div>
        <a th:href="@{/toLogin}">去登录</a><br><br>
        <a th:href="@{/toRegister}">去注册</a>
    </div>
</div>
</body>
</html>
View Code

 

注册register.html的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
    <script th:src="@{/js/jquery.min.js}"></script>
    <script type="text/javascript" th:inline="javascript">
        debugger;
        function checkBpwd() {
            if($("#username").val()==""){
                alert("用户名必须输入");
                $("#username").focus();
                return false;
            } else if($("#password").val()==""){
                alert("密码必须输入");
                $("#password").focus();
                return false;
            }else if($("#password").val()!=$("#repassword").val()){
                alert("两次密码不一致");
                $("#password").focus();
                return false;
            }else{
                document.myForm.submit();
            }
        }
    </script>
</head>
<body>
<div class="container">
    <div class="bg-primary" style="width:100%;height:70px;padding-top: 10px"><h2 align="center">用户注册</h2></div>
    <br>
    <br>
    <form th:action="@{/register}" name="myForm" method="post" th:object="${userDomain}" class="form-horizontal" role="form">
        <div class="form-group has-success">
            <label class="col-sm-2 col-md-2 control-label">用户名</label>
            <div class="col-sm-4 col-md-4">
                <input type="text" class="form-control"
                       placeholder="请输入你的用户名" th:field="*{username}">
            </div>
        </div>
        <div class="form-group has-success">
            <label class="col-sm-2 col-md-2 control-label">密码</label>
            <div class="col-sm-4 col-md-4">
                <input type="password" class="form-control"
                       placeholder="请输入你的密码" th:field="*{password}">
            </div>
        </div>
        <div class="form-group has-success">
            <label class="col-sm-2 col-md-2 control-label">确认密码</label>
            <div class="col-sm-4 col-md-4">
                <input type="password" class="form-control"
                       placeholder="请再次输入你的密码" th:field="*{repassword}">
            </div>
        </div>
        <br>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="button" onclick="checkBpwd()" class="btn btn-success">注册</button>
                <button type="reset" class="btn btn-primary">重置</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>
View Code

 

登录login.html的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
    <script th:src="@{/js/jquery.min.js}"></script>
    <script type="text/javascript">
        $(function () {
            $("#loginBtn").click(function () {
                var username=$("#username");
                var password=$("#password");
                var msg="";
                if (username.val()==""){
                    msg="用户名不能为空";
                    username.focus();
                }
                if (password.val()==""){
                    msg="密码不能为空";
                    password.focus();
                }
                if(msg!=""){
                    alert(msg);
                    return false;
                }
                //$("#myForm").submit();
                document.myForm.submit();
            });
        });
    </script>
</head>
<body>
<div class="container">
    <div class="bg-primary" style="width: 100%;height:70px;padding-top: 10px"><h2 align="center">用户登录</h2></div>
    <br>
    <br>
    <form th:action="@{/login}" name="myForm" method="post"  class="form-horizontal" role="form">
        <div th:if="${param.error!=null}">
            <div class="alert alert-danger">
                <p><font color="red">用户名或者密码错误</font></p>
            </div>
        </div>
        <div th:if="${param.logout!=null}">
            <div class="alert alert-success">
                <p><font color="red">注销成功</font></p>
            </div>
        </div>
        <div class="form-group has-success">
            <label  class="col-sm-2 col-md-2 control-label">用户名</label>
            <div class="col-sm-4 col-md-4">
                <input type="text" class="form-control"
                       placeholder="请输入你的用户名" name="username" id="username">
            </div>
        </div>
        <div class="form-group has-success">
            <label  class="col-sm-2 col-md-2 control-label">密码</label>
            <div class="col-sm-4 col-md-4">
                <input type="password" class="form-control"
                       placeholder="请输入你的密码"  name="password"  id="password">
            </div>
        </div>
        <br>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="button" id="loginBtn" class="btn btn-success">登录</button>
                <button type="reset" class="btn btn-primary">重置</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>
View Code

 

拒绝访问deniedAccess.html的代码如下:
 
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">拒绝访问页面</h3>
    </div>
</div>
<div class="container">
    <div>
        <h3><span th:text="${user}"></span>您没有权限访问该页面!您的权限是<span th:text="${role}"></span></h3>
        <a th:href="@{/logout}">安全退出</a>
    </div>
</div>
</body>
</html>
View Code

 

管理员用户认证成功后访问的页面main.html的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">管理员页面</h3>
    </div>
</div>
<div class="container">
    <div>
        <h3>欢迎<span th:text="${user}"></span>访问该页面!您的权限是<span th:text="${role}"></span></h3>
        <br><br>
        <a th:href="@{/user/loginSuccess}">去访问用户登录成功界面</a>
        <a th:href="@{/logout}">安全退出</a>
    </div>
</div>
</body>
</html>
View Code

 

普通用户认证成功后访问的页面loginAccess.html的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">登录成功页面</h3>
    </div>
</div>
<div class="container">
    <div>
        <h3>欢迎<span th:text="${user}"></span>登录成功!您的权限是<span th:text="${role}"></span></h3>
        <br><br>
        <a th:href="@{/admin/main}">去访问管理员功界面</a>
        <a th:href="@{/logout}">安全退出</a>
    </div>
</div>
</body>
</html>
View Code

 

12、修改Application类

在SecurityMybatisApplication类头部使用@MapperScan注解扫描Mapper接口。
具体代码如下:
package com.mm.security_mybatis;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.mm.security_mybatis.repository")
public class SecurityMybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecurityMybatisApplication.class, args);
    }

}
View Code

 

13、测试应用

运行SecurityMybatisApplication的主方法启动项目。
Spring Boot启动后,观察控制台,发现MySecurityConfigurerAdapter的两个config方法都已经被执行,说明自定义的用户认证和用户授权工作已经生效。

 

 

 

 在浏览器输入“http://localhost:8080/sm”

 

 

http://localhost:8080/sm/toRegister、http://localhost:8080/sm/toregister:

 

 

http://localhost:8080/sm/toLogin、http://localhost:8080/sm/login:

 

 

 

 

 管理员登录成功界面:用户:admin

 

 

 

 

 

 

普通用户登录界面:用户:mm

 

 

 

 

 

 

14、附数据库脚本

 创建数据库:

CREATE DATABASE springtest CHARACTER SET utf8 COLLATE utf8_general_ci;

 

用户表user:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
View Code

 权限表authority:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for authority
-- ----------------------------
DROP TABLE IF EXISTS `authority`;
CREATE TABLE `authority`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of authority
-- ----------------------------
INSERT INTO `authority` VALUES (1, 'ROLE_ADMIN');
INSERT INTO `authority` VALUES (2, 'ROLE_DBA');
INSERT INTO `authority` VALUES (3, 'ROLE_USER');

SET FOREIGN_KEY_CHECKS = 1;
View Code

 

用户权限映射表user_authority:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user_authority
-- ----------------------------
DROP TABLE IF EXISTS `user_authority`;
CREATE TABLE `user_authority`  (
  `user_id` int(11) NOT NULL,
  `authority_id` int(11) NOT NULL,
  INDEX `FKgvxjs381k6f48d5d2yi11uh89`(`authority_id`) USING BTREE,
  INDEX `FKpqlsjpkybgos9w2svcri7j8xy`(`user_id`) USING BTREE,
  CONSTRAINT `FKgvxjs381k6f48d5d2yi11uh89` FOREIGN KEY (`authority_id`) REFERENCES `authority` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `FKpqlsjpkybgos9w2svcri7j8xy` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
View Code

 

posted @ 2022-03-21 10:56  lanrenka  阅读(103)  评论(0编辑  收藏  举报