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

Spring学习笔记(三十四)——Spring Security入门

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

Spring学习笔记(三十四)——Spring Security入门

目录
  • spring security简介
    • 什么是spring security
    • spring security 核心功能
    • spring security 原理
  • spring security实例
    • 初探spring security
    • 使用内存中的用户信息
    • 基于角色 Role 的身份认证

spring security简介 什么是spring security

spring security 是基于 spring 的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。在 Spring framework 基础上,spring security 充分利用了依赖注入(DI)和面向切面编程(AOP)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。是一个轻量级的安全框架。它与 Spring MVC 有很好地集成.

spring security 核心功能

(1)认证(你是谁,用户/设备/系统)
(2)验证(你能干什么,也叫权限控制/授权,允许执行的操作)。

spring security 原理

基于 Filter , Servlet, AOP 实现身份认证和权限验证

spring security实例 初探spring security
  1. 创建 maven 项目
  2. 加入依赖:spring boot 依赖, spring security 依赖

org.springframework.boot
spring-boot-parent
2.0.6.RELEASE



org.springframework.boot
spring-boot-starter-web



org.springframework.boot
spring-boot-starter-security

  1. 创建 Controller,接收请求
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping()
public class HelloSecurityController {

    @RequestMapping("/test1")
    @ResponseBody
    public String sayHello() {
        return "Hello Spring Secuirty 安全管理框架";
    }
}
  1. 框架生成的用户
    用户名: user
    密码: 在启动项目时,生成的临时密码。uuid
    日志中生成的密码
    generated security password: 9717464c-fafd-47b3-9995-2c18b24f7336

  2. 自定义用户名和密码
    需要在 springboot 配置文件中设置登录的用户名和密码
    在 resource 目录下面创建 spring boot 配置文件
    application.yml(application.properties)

    security:
        user:
          name: Nick
          password: Nick
    

    name:自定义用户名称
    password:自定义密码

  3. 关闭验证

    //排除Security的配置,让他不启用
    @SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
    //@SpringBootApplication
    public class SercurityTest1Application {
    
        public static void main(String[] args) {
            SpringApplication.run(SercurityTest1Application.class, args);
        }
    }
    
使用内存中的用户信息

使用内存中的用户信息是指在服务器的内存中简单的配置用户信息,进行权限相应的配置,可以更灵活的进行功能测试,并没有使用数据库。
1)使用:WebSecurityConfigurerAdapter 控制安全管理的内容。
需要做的使用:继承 WebSecurityConfigurerAdapter,重写方法。实现
自定义的认证信息。重写下面的方法。
protected void configure(AuthenticationManagerBuilder auth)
2)spring security 5 版本要求密码进行加密,否则报错
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
实现密码加密:

  • 创建用来加密的实现类(选择一种加密的算法)
@Bean
public PasswordEncoder passwordEncoder(){
	//创建 PasawordEncoder 的实现类, 实现类是加密算法
	return new BCryptPasswordEncoder();
}
  • 给每个密码加密
PasswordEncoder pe = passwordEncoder();
pe.encode("123456")

3)示例代码如下

package cn.kt.sercurity_test1.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.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;
import org.springframework.security.crypto.password.PasswordEncoder;





@Configuration
@EnableWebSecurity
public class MySecurityConfig {

    //在方法中配置用户和密码的信息、作为登录信息
    //定义两个角色 normal  admin
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder pe = passwordEncoder();
        auth.inMemoryAuthentication().withUser("admin").password(pe.encode("admin")).roles();
        auth.inMemoryAuthentication().withUser("Nick").password(pe.encode("Nick")).roles();
        auth.inMemoryAuthentication().withUser("Amy").password(pe.encode("Amy")).roles();
    }

    //创建密码的加密类
    @Bean
    public PasswordEncoder passwordEncoder() {
        //创建PasswordEncoder的实现类,实现类是加密算法
        return new BCryptPasswordEncoder();
    }
}

注解:

  1. @Configuration :表示当前类是一个配置类(相当于是 spring 的 xml
    配置文件),在这个类方法的返回值是 java 对象,这些对象放入到
    spring 容器中。
  2. @EnableWebSecurity:表示启用 spring security 安全框架的功能
  3. @Bean:把方法返回值的对象,放入到 spring 容器中。
基于角色 Role 的身份认证

基于角色的实现步骤:

1、设置用户的角色
继承 WebSecurityConfigurerAdapter
重写 configure 方法。指定用户的 roles
auth.inMemoryAuthentication().withUser("admin").password(pe.encode("admin")).roles("admin","normal");
2、在类的上面加入启用方法级别的注解
@EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
}

加上@EnableGlobalMethodSecurity(prePostEnabled = true)注解之后在方法层面,就可以手动使用使用@PreAuthorize 指定在方法之前进行角色的认证,指定方法可以访问的角色列表。
如:hasAnyRole(‘角色名称 1’,‘角色名称 N’);

	package cn.kt.sercurity_test1.controller;
	
	import org.springframework.security.access.prepost.PreAuthorize;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.RestController;
	
	
	@RestController
	public class AuthorizeSecurityController {
	    //指定 normal和admin都可以访问的通用的方法
	    @RequestMapping("/testUser")
	    @PreAuthorize(value = "hasAnyRole('admin','normal')")
	    public String testUser() {
	        return "Hello Spring Secuirty normal和admin都可以访问的通用的方法";
	    }
	
	    //指定 admin访问的专有的方法
	    @RequestMapping("/testAdmin")
	    @PreAuthorize(value = "hasAnyRole('admin')")
	    public String testAdmin() {
	        return "Hello Spring Secuirty admin访问的专有的方法";
	    }
	}

3、或者在配置类中,进行权限的统一配置
如以下编写的配置类:

package cn.kt.securitytest2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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;

// @EnableWebSecurity已经自动导入了配置注解@Configuration,可以不不用重复添加
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //定制请求的授权规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1*.html",
                "*.css",
                "*.js",
                "/webSocket/**"
        ).permitAll();
    }

    //定义认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        PasswordEncoder pe = passwordEncoder();
        auth.inMemoryAuthentication()
                .withUser("zhangsan").password(pe.encode("123456")).roles("VIP1", "VIP2")
                .and()
                .withUser("lisi").password(pe.encode("123456")).roles("VIP2", "VIP3")
                .and()
                .withUser("wangwu").password(pe.encode("123456")).roles("VIP1", "VIP3");
    }

    //创建密码的加密类
    @Bean
    public PasswordEncoder passwordEncoder() {
        //创建 PasawordEncoder 的实现类, 实现类是加密算法
        return new BCryptPasswordEncoder();
    }
}

注意:

  1. 重写protected void configure(HttpSecurity http) throws Exception {}方法进行权限的授权控制
  2. http.authorizeRequests().antMatchers("/").permitAll()表示所有人可以访问”/“首页;http.authorizeRequests().antMatchers("/level1/**").hasRole(“VIP1”)表示只有有"VIP1"权限的人,才可以访问”/level1/xxx"页面下的内容。相应的很有必要添加静态资源不需要授权。
  3. http.formLogin()开启自动配置的登陆功能,效果:如果没有登陆,没有权限就会来到登陆页面,相应的也可以按照代码中的注释来自定义登录规则
  4. http.logout().logoutSuccessUrl("/")开启自动配置的注销功能,注销成功以后来到首页,并且清空session
  5. http.rememberMe()开启记住我功能,会将cookie发给浏览器保存,以后访问页面带上这个cookie,只要通过检查就可以免登录
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344876.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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