栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring Security】从入门到精通

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring Security】从入门到精通

文章目录
  • 【前言】
  • 【正文】
    • 一、简介
    • 二、入门案例
      • (一)创建maven工程
      • (二)配置 pom.xml 文件
      • (三)创建登录成功后的页面 index.html
      • (四)配置springmvc的核心控制器 web.xml
      • (五)配置自动配置 spring-security.xml
      • (六)展示结果
    • 三、进阶案例
      • (一)配置可匿名访问的资源
        • (1)案例要求:
        • (2)实现配置:
          • 第一步:在项目中创建js、css目录并在两个目录下提供任意一些测试文件
          • 第二步:配置 spring-security.xml
      • (二)自定义登录页
        • (1)案例要求:
        • (2)实现配置:
          • 第一步:提供login.html作为项目的登录页面
          • 第二步:修改spring-security.xml文件
            • 1:指定login.html页面可以匿名访问,否则无法访问
            • 2:关闭盗链安全请求
            • 3:加入表单登录信息的配置
          • 第三步:结果展示
      • (三)从数据库查询用户信息
        • (1)案例要求:
        • (2)实现配置:
          • 第一步:创建java bean对象
          • 第二步:定义UserService类,实现UserDetailsService接口
          • 第三步:修改spring-security.xml文件
      • (四)对密码进行加密
        • (1)常见加密方式
        • (2)MD5加密
          • 第一步:导入MD5Utils工具类
          • 第二步:创建测试类
          • 第三步:运行查看结果
        • (3)bcrypt加密
          • 第一步:修改spring-security.xml文件
          • 第二步:创建测试类
          • 第三步:运行查看结果
          • 第四步:修改UserService实现类
          • 第五步:运行查看结果
      • (五)配置多种校验规则(对页面)
        • (1)案例要求:
        • (2)实现配置:
          • 第一步:修改spring-security.xml文件
          • 第二步:测试结果


【前言】

Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证和授权的过程。本文将对Spring Security进行从入门到进阶的讲解。

【正文】 一、简介
  1. SpringSecurity是Spring家族的一个安全框架, 简化我们开发里面的认证和授权过程
  2. SpringSecurity内部封装了Filter(只需要在web.xml容器中配置一个过滤器–代理过滤器,真实的过滤器在spring的容器中配置)
  3. 常见的安全框架
    • Spring的 SpringSecurity:https://spring.io/projects/spring-security/
    • Apache的Shiro: http://shiro.apache.org/
二、入门案例 (一)创建maven工程

(二)配置 pom.xml 文件


    4.0.0

    com.securitylearn
    spring_security_demo
    1.0-SNAPSHOT
    war
    
        5.0.5.RELEASE
        UTF-8
        1.8
        1.8
    

    
        
            org.springframework
            spring-core
            ${spring.version}
        
        
            org.springframework
            spring-web
            ${spring.version}
        
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
        
            org.springframework
            spring-context-support
            ${spring.version}
        
        
            org.springframework
            spring-test
            ${spring.version}
        
        
            org.springframework
            spring-jdbc
            ${spring.version}
        
        
            org.springframework.security
            spring-security-web
            5.0.5.RELEASE
        
        
            org.springframework.security
            spring-security-config
            5.0.5.RELEASE
        
        
            javax.servlet
            servlet-api
            2.5
            provided
        
    
    
        
            
                org.apache.tomcat.maven
                tomcat7-maven-plugin
                
                    
                    85
                    
                    /
                
            
        
    
    

(三)创建登录成功后的页面 index.html



    
    Title



登录成功

(四)配置springmvc的核心控制器 web.xml

在web.xml 中主要配置 SpringMVC 的 DispatcherServlet 和用于整合第三方框架的DelegatingFilterProxy代理过滤器,

真正的过滤器在spring的配置文件,用于整合Spring Security。




    
        
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
    
    
        springSecurityFilterChain
        
public class User {

    private String username;
    private String password;
    private String telephone;

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + ''' +
                ", password='" + password + ''' +
                ", telephone='" + telephone + ''' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }
}

第二步:定义UserService类,实现UserDetailsService接口

UserDetailsService接口
在spring配置文件中注册UserService,指定其作为认证过程中根据用户名查询用户信息的处理类。
当我们进行登录操作时,spring security框架会调用UserService的loadUserByUsername方法查询用户信息,并根据此方法中提供的数据库中的密码和用户页面输入的表单密码进行比对来实现认证操作。

package com.seclearn.service;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.HashMap;
import java.util.List;
import java.util.Map;



@Service    //声明bean对象,id就是类名首字母小写 id="userDetailsService"
public class UserDetailsServiceImpl implements UserDetailsService {

    //模拟数据库中的用户数据
    static Map map = new HashMap<>();

    static {
        com.seclearn.pojo.User user1 = new com.seclearn.pojo.User();
        user1.setUsername("admin");
        user1.setPassword("admin");
        user1.setTelephone("123");

        com.seclearn.pojo.User user2 = new com.seclearn.pojo.User();
        user2.setUsername("txg");
        user2.setPassword("txg");
        user1.setTelephone("321");

        map.put(user1.getUsername(), user1);
        map.put(user2.getUsername(), user2);
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //表示从数据库查询数据 模拟
        com.seclearn.pojo.User user = map.get(username);
        if (user == null) {
            return null;    //用户不存在只需要返回null,框架会自动跳转到登录页
        }

        String password = "{noop}" + user.getPassword();

        //角色:角色是权限的集合
        List lists = new ArrayList<>();
        lists.add(new SimpleGrantedAuthority("add"));
        lists.add(new SimpleGrantedAuthority("delete"));    //用权限名称表示权限,直接使用权限名称即可
        lists.add(new SimpleGrantedAuthority("ROLE_ADMIN"));    //用角色表示权限时,需增加“ROLE_”前缀

        //使用框架提供的User 实现UserDetail接口
        return new org.springframework.security.core.userdetails.User(user.getUsername(),password,lists);
    }
}

第三步:修改spring-security.xml文件

    
        
    

如果没有配置扫描包,需要配置:

 
    
(四)对密码进行加密 (1)常见加密方式

前面我们使用的密码都是明文的,这是非常不安全的;一般情况下用户的密码需要进行加密后再保存到数据库中。

常见的密码加密方式有:

  • 3DES、AES、DES:使用对称加密算法,可以通过解密来还原出原始密码;
  • MD5、SHA1:使用单向HASH算法,无法通过计算还原出原始密码,但是可以建立彩虹表进行查表破解;
  • MD5:可进行加盐加密,保证安全;
(2)MD5加密 第一步:导入MD5Utils工具类

package com.seclearn.util;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
	
	public static String md5(String plainText) {
		byte[] secretBytes = null;
		try {
			secretBytes = MessageDigest.getInstance("md5").digest(
					plainText.getBytes());
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException("没有md5这个算法!");
		}
		String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
		// 如果生成数字未满32位,需要前面补0
		for (int i = 0; i < 32 - md5code.length(); i++) {
			md5code = "0" + md5code;
		}
		return md5code;
	}

	public static void main(String[] args) {
		System.out.println(md5("1234"));
	}
}
第二步:创建测试类
package com.seclearn;

import com.seclearn.util.MD5Utils;


public class TestMD5 {
    public static void main(String[] args) {
        String s1 = MD5Utils.md5("123");
        String s2 = MD5Utils.md5("123");
        System.out.println("s1 = " + s1);
        System.out.println("s2 = " + s2);
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
    }
}

第三步:运行查看结果

同样的密码值,盐值不同,加密的结果不同。

(3)bcrypt加密

bcrypt: 将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题

Spring security中的BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密。

SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。

(1)加密(encode): 注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。

(2)密码匹配(matches): 用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的),而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。如果两者相同,说明用户输入的密码正确。

这正是为什么处理密码时要用hash算法,而不用加密算法。因为这样处理即使数据库泄漏,黑客也很难破解密码。

第一步:修改spring-security.xml文件

指定密码加密对象


    
    
        
        
    





第二步:创建测试类
package com.seclearn;

import org.junit.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


public class TestSpringSecurity {

    // SpringSecurity加盐加密
    @Test
    public void testSpringSecurity(){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String s = encoder.encode("abc");
        System.out.println(s);
        String s1 = encoder.encode("abc");
        System.out.println(s1);

        // 进行判断 先生成一个,复制到这里做比对
        boolean b = encoder.matches("abc", "$2a$10$dyIf5fOjCRZs/pYXiBYy8uOiTa1z7I.mpqWlK5B/0icpAKijKCgxe");
        System.out.println(b);
    }
}
第三步:运行查看结果

加密后的格式一般为:

$2a$10$/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa

加密后字符串的长度为固定的60位;

$是分割符,无意义;
2a是bcrypt加密版本号;
10是cost的值;
而后的前22位是salt值;
再然后的字符串就是密码的密文了。

第四步:修改UserService实现类

将密码设置为加密后的密文

static {
        com.seclearn.pojo.User user1 = new com.seclearn.pojo.User();
        user1.setUsername("admin");
        user1.setPassword("$2a$10$BkHeHArjzunbXzlgTtxi9.PUSV7nPn56w6fA4hEkuN8wd6EbtQeyi");
        user1.setTelephone("123");

        com.seclearn.pojo.User user2 = new com.seclearn.pojo.User();
        user2.setUsername("txg");
        user2.setPassword("$2a$10$BljUMVT6/IXyLBOuUGRRfeLbt8ytfgiMccNOz8rXXdP.dGCbetGU.");
        user1.setTelephone("321");

        map.put(user1.getUsername(), user1);
        map.put(user2.getUsername(), user2);
    }
		//String password = "{noop}" + user.getPassword();
        String password = user.getPassword();
第五步:运行查看结果

再重新install项目,重新运行之后再次输入账号密码,可以登录成功。

(五)配置多种校验规则(对页面) (1)案例要求:

对访问的页面做权限控制

(2)实现配置:

为了测试方便,首先在项目的webapp文件夹下面创建 a.html、b.html、c.html、d.html几个页面

第一步:修改spring-security.xml文件

   
    
    
    

    
    

    
    

    
    


第二步:测试结果

登录后可以访问a.html,b.html,c.html,不能访问d.html




以上就是Spring Security的知识介绍啦,欢迎阅读~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340745.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号