springboot整合springsecrity的使用

本人小菜鸡 见谅

pom配置

    <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.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

config配置

package com.hexu.demo3.config;

import com.hexu.demo3.service.impl.UserDetailsServiceImpl;
import com.hexu.demo3.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
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.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;

/**
 * 安全框架
 * @author 86176
 */
@EnableWebSecurity  //开启
@Configuration
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Resource
    UserDetailsServiceImpl userDetailsServiceImpl;

    /**
     * 自定义MD5加密就这样写
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //数据库是明文的话按下面就行了
        //auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(new BCryptPasswordEncoder());

        //数据库不是明文  我用的是MD5加密
        auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(new PasswordEncoder() {

            @Override
            public String encode(CharSequence charSequence) {
                return MD5Util.getMD5((String) charSequence);
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return s.equals(MD5Util.getMD5((String) charSequence));
            }
        });
    }


    //权限认证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//给页面添加认证    不同级别进入不同的页面  antMatchers(“页面”) hasRole(“角色”)
        http.authorizeRequests().antMatchers("/", "/lo").permitAll()
                .antMatchers("/vip").hasAnyRole("VIP", "SSVIP", "SVIP")
                .antMatchers("/svip").hasAnyRole("SVIP", "SSVIP")
                .antMatchers("/ssvip").hasRole("SSVIP");
        //没有登录返回自带的登录页面  loginPage(“自定义登陆页面”)
        http.formLogin().loginPage("/lo").loginProcessingUrl("/login").successForwardUrl("/").failureUrl("/lo").permitAll();
        //启动记住我功能  rememberMeParameter(“跟登陆页面的记住我复选框name值一致”)
        http.rememberMe().rememberMeParameter("remember");
        //退出页面  logoutSuccessUrl退出的地址
        http.logout().logoutSuccessUrl("/").invalidateHttpSession(true).deleteCookies();

        // 关闭 csrf 防护
        http.csrf().disable();

    }
}
//权限列名值要以  ROLE_开头   hasRole(ROLE_后面的权限)

工具类

md5加密

package com.hexu.demo3.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {
    /**
     * 1.MD5(message-digest algorithm 5)信息摘要算法,
     *   它的长度一般是32位的16进制数字符串(如81dc9bdb52d04dc20036dbd8313ed055)
     * 2.由于系统密码明文存储容易被黑客盗取
     * 3.应用:注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
     *       登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对
     * 4.md5不可逆,即没有对应的算法,从产生的md5值逆向得到原始数据。
     *   但是可以使用暴力破解,这里的破解并非把摘要还原成原始数据,如暴力枚举法。
     *
     */
    public final static String getMD5(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");//创建具有指定算法名称的摘要
            md.update(str.getBytes());                    //使用指定的字节数组更新摘要
            byte mdBytes[] = md.digest();                 //进行哈希计算并返回一个字节数组

            String hash = "";
            for(int i= 0;i<mdBytes.length;i++){           //循环字节数组
                int temp;
                if(mdBytes[i]<0)                          //如果有小于0的字节,则转换为正数
                    temp =256+mdBytes[i];
                else
                    temp=mdBytes[i];
                if(temp<16)
                    hash+= "0";
                hash+=Integer.toString(temp,16);         //将字节转换为16进制后,转换为字符串
            }
            return hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

service

package com.hexu.demo3.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hexu.demo3.dao.UserDao;
import com.hexu.demo3.pojo.User;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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 org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * 数据库登录类
 * @author 86176
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    UserDao userDao;
    @Override
    public UserDetails loadUserByUsername(String s) throws AuthenticationException  {
        QueryWrapper<User> queryWrap=new QueryWrapper<>();
        queryWrap.eq("name",s);
        User user = userDao.selectOne(queryWrap);
        Assert.notNull(user,"账号不存在");
       //权限
        List<GrantedAuthority> vip = AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRake());
        //  没有用MD5加密就用这个      new BCryptPasswordEncoder().encode(user.getPass())
        return new org.springframework.security.core.userdetails.User(user.getName(),user.getPass(),vip);
    }
}

controller

package com.hexu.demo3.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class hello {

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

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

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

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

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

前端页面

home.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<!--没有登陆显示登陆-->
<div sec:authorize="isAnonymous()">
  <a href="/lo">登录</a>
</div>
<!--登陆的显示退出 并且显示当前的权限-->
<div sec:authorize="!isAnonymous()">
  用户名<span sec:authentication="name"></span>
  角色<span sec:authentication="authorities"></span>
  <a href="/logout">退出</a>
</div>

<!--级别访问-->
<a sec:authorize="hasAnyRole('ROLE_VIP','ROLE_SSVIP','ROLE_SVIP')" href="/vip">vip通道</a>
<a sec:authorize="hasAnyRole('ROLE_SVIP','ROLE_SSVIP')" href="/svip">svip通道</a>
<a sec:authorize="hasAnyRole('ROLE_SSVIP')" href="/ssvip">大王vip通道</a>

</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
账号  <input type="text" name="username">
密码  <input type="password" name="password">
记住我    <input type="checkbox" name="remember">
  <input type="submit" value="登录">
</form>
</body>
</html>

ssvip.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
恭喜SSVIP进入

</body>
</html>

svip.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
恭喜SVIP进入

</body>
</html>

vip.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
恭喜VIP进入
</body>
</html>

结果

登陆页面

springboot整合springsecrity的使用

svip用户登陆

springboot整合springsecrity的使用

ssvip用户登陆

springboot整合springsecrity的使用

上一篇:Spring Security(1-7) Spring Security 中自定义异常处理


下一篇:Spring Security核心组件之安全上下文