SpringSecurity学习 -- 1 springSecurity

news2024/12/28 20:51:38

目录

 简介:

token和jwt的区别

1.快速入门

1.自定义用户名和密码。

自定义重定向。

2.设置权限管理

3.从路径中获取用户信息

2.SpringSecurity核心组件

SecurityContext : authentication对象的容器。

SecurityContextHolder :

Authentication:

​编辑

UserDetails: 存储用户信息的。

UserDetailsService:

AuthenticationManager

3.配置类开发

权限判断

角色判断

IP判断(我的版本废除了)

access 

4.注解开发(了解)

@secured注解(角色判断)

@PreAuthorize + @PostAuthorize注解

@RemeberMe(前后端分离后,我觉得没必要)

Thymleaf(了解)  

CSRF(了解):

总结


 简介:

springSecuicty是spring的一个安全框架,主要负责处理认证授权的功能。

认证:认证当前用户是哪个用户,并具体那个用户。(是否登录)

授权:授予某个用户访问权限,并判断他到底是否有访问权限。(有无权限执行:VIP)

其他的安全感框架:apache shiro ,强大且已于上手的安全框架

授权:貌似底层就想着一个过滤器,Filter从用户的请求判断是否携带相应的请求体来做出相应的相应。

token和jwt的区别

jwt是token的一种复杂实现。

jwt:  全称 json web token 比较复杂,有头部,载荷、签名组成。载荷中,包括用户信息等,并且服务端用秘钥对Jwt进行签名。发给浏览器端,浏览器端,访问时对jwt进行解密,如果解密成功则就是验证成功。

总结 : jwt是一种更复杂的身份令牌信息。

1.快速入门

我们基于web项目做测试

 1.核心依赖

<dependencies>
		<!-- spring-security依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<!-- web依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
     </dependencies>
		

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring-boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

2.我们建一个login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="">
    <input type="text" placeholder="用户名">
    <input type="text" placeholder="密码">
</form>

</body>
</html>

3.启动springboot项目,访问locahost:8080(你没改端口号的话)

 重定向到了这个页面,同时控制台打印一串类似密码的数字。

 证明security已经成功了。

1.自定义用户名和密码。

自定义重定向。

successForwardUrl(),只能重定向到静态页面。我们点进去发现,

 看得出实际上,我们调用successHanler()方法,然后我们url被封装到这里面。

 卧槽,发现了什么?请求转发,看来我们url就被封装在这里面,被进行请求转发。

那为什么,全url为什么不能跳转,上述构造器,有一个断言,看url,符不符合格式,否则,那个跳转对象拿到是url是null。

嗯,看来,我们就是要自定义一个类实现AuthenticationSuccessHandler接口,借鉴上述并进行重写。

限制使用。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin().and()
                .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.
                inMemoryAuthentication()
                .withUser("qhx2004")
                .password("{noop}123456").roles("USER");

    }
}

2.设置权限管理

@Configuration
@EnableWebSecurity
// 配置security注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                //  设置资源对应的访问角色权限
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest()
                .authenticated()
                .and()
                .formLogin().and()
                .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.
                inMemoryAuthentication()
                // 登录账号匹配权限
                .withUser("qhx2004").password("{noop}123456").roles("USER").and()
                .withUser("admin").password("{noop}111").roles("ADMIN", "USER");
        // PassWordEncode
    }
}

3.从路径中获取用户信息

	@RequestMapping("/info")
	@ResponseBody
	public String productInfo(){
		String currentUser = "";
		Object principl = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if(principl instanceof UserDetails) {
			currentUser = ((UserDetails)principl).getUsername();
		}else {
			currentUser = principl.toString();
		}
		return " some product info,用户信息 is: "+currentUser;
	}

2.SpringSecurity核心组件

SecurityContext : authentication对象的容器。

SecurityContextHolder :

Authentication:

它包括这很多,诸如用户信息、证书、用户权限、用户身份之类的。看方法,几乎使我们用来获取的,看样子他是别人调用我们拿到的。

public interface Authentication extends Principal, Serializable {
 
	Collection<? extends GrantedAuthority> getAuthorities();
	Object getCredentials();
	Object getDetails();
	Object getPrincipal(); // 拿去UserDetail对象的
	boolean isAuthenticated();
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

UserDetails: 存储用户信息的。

public interface UserDetails extends Serializable {

	Collection<? extends GrantedAuthority> getAuthorities();
	String getPassword();
	String getUsername();
	boolean isAccountNonExpired();
	boolean isAccountNonLocked();
	boolean isCredentialsNonExpired();
	boolean isEnabled();
}

UserDetailsService:

public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String password = "1234";
        // 1.我们来自前端的用户名,会调用数据库进行查询,如果成功!
        if ("123".equals(username)) {
            // 失败 ,抛异常
            throw new UsernameNotFoundException("用户并校验错误!");
        }
        // 成功,返回一个User(UserDetails的实现类,我们的用户信息就封装在这个对象里面)对象
        return new User(username, password, AuthorityUtils.createAuthorityList("12"));
    }
}

AuthenticationManager

public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
}

用来检验你的Authentication对象是否正确的。

3.配置类开发

server:
  servlet:
    context-path: /qhx
// 给项目 + 路径前缀

 访问以下资源放行卧槽,反正,我们yml文件整,给项目加了前缀/qhx,看出来区别了。mvc就是专门加了,servletpath

  // 授权认证
        http.authorizeHttpRequests()
                // 放行路径资源
                // 一般匹配
                .antMatchers("/qhx/login.html").permitAll()
                // mvc匹配
                .mvcMatchers("/login").servletPath("qhx").permitAll()
                // 正则匹配
                .regexMatchers("/qhx/register").permitAll()
                .anyRequest().authenticated();
        // 所有请求都必须被认证,必须登录之后被访问。

内置访问方法解析,

权限判断

1.测试

  return new User(username, password, AuthorityUtils.
                       // 登陆之后,我给他admin权限
                        commaSeparatedStringToAuthorityList("admin,ROLE_ADMIN"));
    }

2. 资源限定权限访问

  .antMatchers("/vip").hasAuthority("admin")
                // 放行:admin.admiN访问
                .antMatchers("/vip").hasAnyAuthority("admin", "admiN")
                .anyRequest().authenticated();

角色判断

看出来,规定资源能被什么角色访问,登录之后把相应的角色给你,在这里面,也就是说管理员同时具有管理员和普通用户访问资源的权限。

1.测试

  return new User(username, password, AuthorityUtils.
                // 这个用户能访问普通用户和管理员角色访问的资源
                        commaSeparatedStringToAuthorityList("qhx,wls,ROLE_ADMIN,ROLE_USER"));
    }

 2.资源限定角色访问

// 角色管控:限定下面这俩资源,一个管理员访问,另一个普通用户访问
                .antMatchers("/admin").hasRole("ADMIN")
                .antMatchers("/user").hasAnyRole("ADMIN", "USER")
                .anyRequest().authenticated();

IP判断(我的版本废除了)

access 

我们打开源码,发现实际上是调用同对象的access方法,同理我们也可直接用access调用。

access还支持自定方法。

public class MyServiceImpl implements MyService {
    @Override
    public boolean hasProm(HttpServletRequest request, Authentication authentication) {
        Object principal = authentication.getPrincipal(); // 拿到user对象
        if (principal instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) principal; // 强转
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
            return authorities.contains(new SimpleGrantedAuthority(request.getRequestURI()));

        }

        return false;
    }
}

4.注解开发(了解)

其实看出来为了迎合发展方向,为了迎合我们的配置,就是静态资源和动态一起过滤,但是呢?随着,前后端分离,但是注解开发也是趋势。

@secured注解(角色判断)

1.启动类加上 EnableGlobalMethodSecurity


@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true) // 开启注解启动角色权限(本质上,我们限制的路径资源访问权限)
public class Sspring1securityApplication {

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

}

2.动态资源加上

@RestController
public class LoginContreoller {

    @Secured("ROLE_admin") // 管理员权限能访问
    @GetMapping("/login11")
    public String login() {
        System.out.println("执行登录..");
        return "redirect:main.html";
    }

}

错误:会报500异常,AccessDeniedException(访问被拒绝错误)

@PreAuthorize + @PostAuthorize注解

一个在类和方法执行之前权限判断,一个之后判断。

好家伙之前,我们的权限判断角色控制他都能用,只要输入相应的权限表达式即可。

  //@Secured("ROLE_admin") // 管理员权限能访问
    @PreAuthorize("hasRole('admin')") // 拥有管理员角色权限才能访问

@RemeberMe(前后端分离后,我觉得没必要)

现在,我们完全不需要记住我,这个关键字,因为默认网站差不多就是一个星期之后需要登录一次,那为什么登陆之后,他怎么判断我们是同一个请求,并且怎么记住一星期呢?

1.通过token来判断的话,我们登录之后,设置一个token被浏览器携带,并在浏览器端计算机硬盘储存一个月。

2.当我们下次登录时,会将token发到服务器端API,如果查询成功,则自动登录。

Thymleaf(了解)  

:模版引擎,能将模版和数据分离,但是又能就和在一起形成特定格式(模版)的产物。

CSRF(了解):

跨域网络协议 、IP地址 、端口 中任意一个不相同,就是跨域请求。

  • http本身无状态。通过cookie来记录客服端身份。在cookie中,会存放session id来识别客户端身份。
  • 在跨域的情况下,session id 可能被第三方恶意劫持,通过这个session id向服务器端发起请求。(也就是伪造了用户身份。)
  • 底层来讲,不就是通过session,cookie来判别用户,访问不同的动态资源。

那么CSRF技术,是通过访问时,同时携带_csrf.token 会与在服务端中的token进行比较,如果成功则允许访问。

总结

SecurityConfig.java

@Configuration
@EnableWebSecurity // 启用security配置
// 自定义配置
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.
                userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }

    @Override
    // 解决静态资源拦截问题(了解)
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/asserts/**");
        web.ignoring().antMatchers("/favicon.ico");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 1.配置登录页并允许访问(没用了),下面2个参数对应表单,最后一个跳转页面。
        http.formLogin().usernameParameter("username").passwordParameter("password").loginPage("/login");
        //2.配置登出页面
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/");
        //3.给API设置权限
        http.authorizeRequests() // 拥有很多权限
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasAnyRole("USER", "ADMIN")
                // 任何请求都需要经过认证
                .anyRequest().authenticated();
        // 4.关闭跨域保护
        http.csrf().disable();

    }

    // 密码加密
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

MyUserDetailsServiceImpl.java

@Configuration
public class MyUserDetailService implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 查询就不可能返回boolean值
        User user = userMapper.findByUserName(username); // 1.查询数据库
        // 2.判断有无用户
        if (user == null) {
            System.out.println(username + "用户没有注册");
            throw new UsernameNotFoundException(username + "用户没有注册");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthority());
    }

    // 获取权限列表
    public List getAuthority() {

        //return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
        return AuthorityUtils.createAuthorityList("ROLE_ADMIN");
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/635731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scala概述及变量和常量的重点

1.什么是scala Scala是一种多范式的编程语言&#xff08;多范式&#xff1a;多种编程方法的意思。有面向过程、面向对象、泛型、函数式四种程序设计方法&#xff09;&#xff0c;其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台&#xff08;Jav…

python语法-面向对象数据分析案例(每日销售额柱状图数据可视化)

面向对象数据分析案例&#xff08;每日销售额柱状图数据可视化&#xff09; 使用工具&#xff1a; Pycharm、面向对象、json模块、pyecharts模块等 实现步骤&#xff1a; 读取数据–封装数据对象–计算数据对象–pyechars绘图 &#xff08;项目数据见文章末参考内容&#xff09…

UDS关于0x36数据传输学习笔记

1.服务说明 客户端使用TransferData服务将数据从客户端传输到服务器&#xff08;下载&#xff09;或从服务器传输到客户端&#xff08;上传&#xff09;。 数据传输方向由前面的RequestDownload或RequestUpload服务定义。如果客户端发起了RequestDownload&#xff0c;则要下载的…

HTML注释

注释 注释的写法&#xff1a; 注释快捷键&#xff1a; 代码&#xff1a; 效果&#xff1a; 总结 答案&#xff1a;

usb 的拓扑结构

usb 驱动开发 usb 的基本概念 这个忽略&#xff0c; 基本上usb 是啥都知道 usb 的拓扑结构 usb 是一种主从结构的系统 usb主机由usb主控之器&#xff08;Host Controller)和根集线器&#xff08;Root Hub&#xff09; 构成 usb 主控制器&#xff1a; 主要负责数据处理(就…

chatgpt赋能python:Python数据合并入门指南

Python数据合并入门指南 数据合并是数据分析和处理中的一个重要步骤。使用Python可以轻松地将多个数据集合并成一个&#xff0c;以实现更综合和完整的数据分析。在本篇关于Python数据合并的入门指南中&#xff0c;我们将介绍两个主要的数据合并方法&#xff1a;concat和merge。…

PolarDB MySQL 联邦查询优化特征(条件下推、按需返回列、LIMIT OFFSET下推)

背景 社区版 MySQL 支持的联邦引擎可以将位于远程数据库实例的表像本地表一样访问&#xff0c;大大方便了用户管理多个数据库实例的数据做聚合查询和分析。但是在性能方面存在着可以优化的地方&#xff1a; 只有在可以使用索引 RANGE/REF 方式扫描时&#xff0c;可以将索引上…

2.21 alarm函数 2.22setitimer定时器函数

2.21 alarm函数 #include <unistd.h> unsigned int alarm(unsigned int seconds);功能&#xff1a;设置定时器&#xff08;闹钟&#xff09;。函数调用&#xff0c;开始倒计时&#xff0c;当倒计时为0的时候&#xff0c; 函数会给当前的进程发送一个信号&#xff1a;SIG…

chatgpt赋能python:Python如何另起一行输出

Python如何另起一行输出 如果你正在学习Python编程&#xff0c;你肯定已经遇到过这个问题&#xff1a;如何另起一行输出&#xff1f; Python是一门非常强大的编程语言&#xff0c;它可以完成各种各样的任务&#xff0c;包括从简单的文本处理到复杂的数据分析和机器学习。但是…

【Paper】2019_Event-triggered based scaled consensus for multi-agent systems

Wu X, Mu X. Event-triggered based scaled consensus for multi-agent systems[C]//2019 Chinese Control Conference (CCC). IEEE, 2019: 5544-5549. 文章目录 1 Introduction2 Preparation and problem description2.1 Graph theory2.2 Problem formulation 3 Centralized a…

chatgpt赋能python:Python怎么变颜色

Python怎么变颜色 Python是一种高级编程语言&#xff0c;因其简单易学、开发效率高、运行速度快等优点而广受开发者欢迎。在Python编程过程中&#xff0c;经常需要输出不同颜色的文字以便于提示用户。那么&#xff0c;Python怎么变颜色呢&#xff1f;本文将为大家介绍Python中…

小型中文版聊天机器人

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 目录 一、简单介绍与参考鸣谢 二、数据集介绍 三、数据预处理 1、重复标点符号表达 2、英文标点符号变为中文标点符号 3、繁…

visionpro与abb机器人通信

视觉把坐标传给机器人&#xff0c;机器人根据坐标去拿料 接线&#xff1a;用的海康的镜头 机器人是PNP输出 海康接个1千欧的电阻 接的机器人db652板14和15口子 VP设置 作为 服务器 abb位客户端 发往abb的xy坐标 通信成功会如下图所示 ABB需要的配置项 ABB多任务走通信把…

chatgpt赋能python:Python如何取消空格提升SEO排名

Python如何取消空格提升SEO排名 作为一种高效的编程语言&#xff0c;Python已经成为了许多网站开发人员和SEO优化人员的首选工具。在网站优化中&#xff0c;取消空格是一个重要的优化技术&#xff0c;它可以提升网站速度&#xff0c;提高网站体验&#xff0c;同时也可以提升SE…

关于使用keil瑞萨A4M2踩过的坑

一、之前在rasc添加的组件不能删除。 下面在rasc添加ThreadX&#xff0c;不只是RTOS&#xff0c;其他组件也出现这种情况。 当去掉组件不使用&#xff0c;重新配置。但是组件还是显示在软件包&#xff0c;导致编译出错。 解决方式&#xff0c;自己琢磨发现&#xff1a; 找到工…

经典多模态模型

整点传统多模态学习 接下来看看经典模型&#xff0c;传统多模态任务是下游任务是图文检索(Image Text Retrieval)&#xff0c;视觉问答&#xff08;VQA&#xff09;&#xff0c;视觉推理&#xff08;Visual Reasoning&#xff09;&#xff0c;视觉蕴含&#xff08;Visual Enta…

总结897

每周小结&#xff1a; 这周将线代强化进行到第3讲&#xff0c;做杨超三大计算 英语每天早上巩固之前背诵的文章&#xff0c;每日一个长难句分析&#xff0c;背单词&#xff0c;做题目&#xff0c;准备六级 专业课&#xff0c;刚开始复习 每日必复习&#xff08;5分钟&#x…

【C/C++数据结构与算法】华为C/C++编程规范

目录 一、文件结构 二、程序版式 三、命名规则 四、表达式与基本语句 五、常量 六、函数设计 七、内存管理 八、C高级特性 一、文件结构 避免头文件被重复引用&#xff0c;用 #pragma once 进行预处理用 <> 引用标注库头文件&#xff0c;用 "" 引用自…

Servlet图书管理系统测试报告

密级 中级 (供内部测试完毕后使用) Servlet图书管理系统 测试报告 报告编号: ServletBMS-TR-1 &#xff08;Servlet Book Management System-Testing Report&#xff09; 部门经理______项目经理______ 开发经理______测试经理______ 研发公司: 第六科技有限公司 用户单…

【Web服用应用】LVS+Keepalived群集

LVSKeepaLived群集 一、Keepalived及其工作原理1.1Keepalived体系主要模块及其作用1.2健康检查的方式&#xff08;探针&#xff09; 二、LVSKeepalived 高可用群集部署2.1LVS部署<font colorred>1.配置负载调度器&#xff08;主、备相同&#xff09;2配置节点服务器 三、…