2021/09/13笔记

news/2025/2/5 12:40:13/

我们于2021/09/13 的学习目标是:SpringSecurity,核心任务为:

1、学习技术:

1)、SpringSecurity简介

2)、SpringSecurity快速入门

3)、UserDetailsService

4)、BCryptPasswordEncoder

5)、自定义登录

6)、认证过程其他常用配置

2、文档总结

1)、SpringSecurity简介

SpringSecurity是是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。

它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了 Spring IoC , DI(控制反转Inversion ofControl,DI:Dependency Injection 依赖注入) 和 AOP(面向切面编程) 功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

2)、SpringSecurity快速入门

pom.xml导入依赖

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

使用浏览器访问http://localhost:8080/,自动跳转到默认登录页面

 

导入spring-boot-starter-security启动器后,Spring Security 已经生效,默认拦截全部请求,如果用户没有登录,跳转到登录页面。

默认的username为user,password打印在控制台中。注意每次运行生成的密码都不一致。

Using generated security password: e04ca9f5-f389-4982-b114-81d6488e0d59

3)、UserDetailsService

当什么也没有配置的时候,账号和密码是由 Spring Security 定义生成的。而在实际项目中账号和密码都是从数据库中查询出来的。所以我们要通过自定义逻辑控制认证逻辑。如果需要自定义逻辑时,只需要实现 UserDetailsService 接口即可。

package org.example.service.imp;import org.springframework.security.core.authority.AuthorityUtils;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.security.crypto.password.PasswordEncoder;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class UserDetailsServiceImpl implements UserDetailsService {@Resourceprivate PasswordEncoder encoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {if(!(s.equals("sdf")))throw new UsernameNotFoundException("用户记录不存在!!");String password = encoder.encode("345");return new User(s,password, AuthorityUtils.commaSeparatedStringToAuthorityList("normal,ROLE_abc,/admin.html"));}}

4)、BCryptPasswordEncoder

BCryptPasswordEncoder 是 Spring Security 官方推荐的密码解析器,是对 bcrypt 强散列方法的具体实现。是基于Hash算法实现的单向加密。可以通过strength控制加密强度,默认 10。

encode():给密码编码

@Test
public void encode() {System.out.println(new BCryptPasswordEncoder().encode("myPwD!234567"));//$2a$10$v5zc4C/OWNry0gb1rZanq.GCqv/2AS.kfzYc.aUfc8sB.vyCABKyW//每次编码生成的字符都不相同}

matches():验证输入的密码与进行编码后的原始密码是否相符

@Test
public void decode(){System.out.println(new BCryptPasswordEncoder().matches("myPwD!234567","$2a$10$v5zc4C/OWNry0gb1rZanq.GCqv/2AS.kfzYc.aUfc8sB.vyCABKyW"));//true
}

upgradeEncoding():如果解析的密码能够再次进行解析且达到更安全的结果则返回true,否则返回 false。默认返回 false

@Test
public void encodeUpgrade() {System.out.println(new BCryptPasswordEncoder().upgradeEncoding("$2a$10$v5zc4C/OWNry0gb1rZanq.GCqv/2AS.kfzYc.aUfc8sB.vyCABKyW"));//false
}

5)、自定义登录

自定义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" /><br/>密码:<input type="password" name="userPwd" /><br/><input type="submit" value="登录" /></form></body></html>

 

编写SecurityConfig配置类

package org.example.config;import org.example.handler.LoginFailHandler;import org.example.handler.LoginSuccessHandler;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;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;import javax.annotation.Resource;/*** 自定义登录配置*/@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Resourceprivate LoginSuccessHandler successHandler;@Resourceprivate LoginFailHandler loginFailHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {//禁用csrfhttp.csrf().disable();//配置自定义登录表单页面信息http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").successForwardUrl("/toMain").failureForwardUrl("/toError").usernameParameter("userName").passwordParameter("userPwd");//资源放行http.authorizeRequests().antMatchers("/login.html").permitAll().anyRequest().authenticated();}@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}public String passwordEncoder(String password) {return new BCryptPasswordEncoder().encode(password);}}

自定义UserDetailServiceImp逻辑类

package org.example.service.imp;import org.springframework.security.core.authority.AuthorityUtils;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.security.crypto.password.PasswordEncoder;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class UserDetailsServiceImpl implements UserDetailsService {@Resourceprivate PasswordEncoder encoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {if(!(s.equals("admin")))throw new UsernameNotFoundException("用户记录不存在!!");String password = encoder.encode("123456");return new User(s,password, AuthorityUtils.commaSeparatedStringToAuthorityList("normal,ROLE_abc,/admin.html"));}}

编写MainController控制器类

package org.example.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class MainController {@RequestMapping("toMain")public String toMain(){return "redirect:main.html";}public String toError(){return "redirect:error.html";}}

6)、认证过程其他常用配置

编写页面error.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>操作失败,请重新登录 <a href= "/login.html">跳转</a></body></html>

 

修改控制器的方法

/*** 失败后跳转页面* @return*/@RequestMapping("/toError")public String toError(){return "redirect:/error.html";}

配置器放行错误页面

//资源放行http.authorizeRequests().antMatchers("/login.html","/error.html")//放行登录页面和错误页面.permitAll().anyRequest().authenticated();

自定义登录成功处理器

使用successForwardUrl()时表示成功后转发请求到地址。内部是通过 successHandler() 方法进行控制成功后交给哪个类进行处理

//FormLoginConfigurer类文件package org.springframework.security.config.annotation.web.configurers;import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> {public FormLoginConfigurer() {super(new UsernamePasswordAuthenticationFilter(), (String)null);this.usernameParameter("username");this.passwordParameter("password");}public FormLoginConfigurer<H> loginPage(String loginPage) {return (FormLoginConfigurer)super.loginPage(loginPage);}public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {((UsernamePasswordAuthenticationFilter)this.getAuthenticationFilter()).setUsernameParameter(usernameParameter);return this;}public FormLoginConfigurer<H> passwordParameter(String passwordParameter) {((UsernamePasswordAuthenticationFilter)this.getAuthenticationFilter()).setPasswordParameter(passwordParameter);return this;}public FormLoginConfigurer<H> failureForwardUrl(String forwardUrl) {this.failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl));return this;}public FormLoginConfigurer<H> successForwardUrl(String forwardUrl) {this.successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl));return this;}public void init(H http) throws Exception {super.init(http);this.initDefaultLoginFilter(http);}protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {return new AntPathRequestMatcher(loginProcessingUrl, "POST");}private String getUsernameParameter() {return ((UsernamePasswordAuthenticationFilter)this.getAuthenticationFilter()).getUsernameParameter();}private String getPasswordParameter() {return ((UsernamePasswordAuthenticationFilter)this.getAuthenticationFilter()).getPasswordParameter();}private void initDefaultLoginFilter(H http) {DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = (DefaultLoginPageGeneratingFilter)http.getSharedObject(DefaultLoginPageGeneratingFilter.class);if (loginPageGeneratingFilter != null && !this.isCustomLoginPage()) {loginPageGeneratingFilter.setFormLoginEnabled(true);loginPageGeneratingFilter.setUsernameParameter(this.getUsernameParameter());loginPageGeneratingFilter.setPasswordParameter(this.getPasswordParameter());loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage());loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl());loginPageGeneratingFilter.setAuthenticationUrl(this.getLoginProcessingUrl());}}
}


http://www.ppmy.cn/news/238250.html

相关文章

10__jsp入门el表达式入门CookieSession

jsp入门&el表达式入门&Cookie&Session 第一部分&#xff1a;jsp入门和el表达式入门 1. jsp的入门 1.1 什么是jsp&#xff1a; &#xff08;1&#xff09;sun公司用于动态网站开发技术servlet&#xff0c;因为使用servlet如果向页面输出内容很麻烦&#xff0c;有…

python模块之feedparser学习使用

今天在看书的时候无意间发现了一个号东西就是feedparser模块&#xff0c;feedparser 号称是一个 universal feed parser&#xff0c;使用它我们可轻松地实现从任何 RSS 或 Atom 订阅源得到标题、链接和文章的条目了&#xff0c;这个号称并不是说的话&#xff0c;是因为这个模块…

收集一些c/c++技术

下面是整理的一些c/c方面的相关代码demo&#xff0c;后续将持续更新下去。 这是单独稍微大一些的项目地址&#xff08;给出博客地址&#xff0c;博客中附带项目git地址&#xff09;&#xff1a;、 标题&#xff1a; 扫雷小游戏 (22条消息) 基于QT开发的扫雷小游戏_GT199309…

进入IT领域,多久能月入过万?

当下打拼的很多人都有这样的困惑&#xff1a;刚毕业或者工作时间不长&#xff0c;也有一些基本技能&#xff0c;对未来有美好憧憬&#xff0c;一身干劲&#xff0c;却拿着微薄的薪水过着捉襟见肘的生活。 有些同龄人进入IT领域后快速升职加薪&#xff0c;观望者经常会问&#…

QMI8658 - 姿态传感的零偏(常值零偏)标定

1. 零偏 理论上在静止状态下三轴输出为0,0,0&#xff0c;但实际上输出有一个小的偏置&#xff0c;这是零偏的静态分量&#xff08;也称固定零偏&#xff09;。 陀螺生产出来后就一直固定不变的零偏值。对于传统的高性能惯性器件来说&#xff0c;该误差在出厂标定时往往就被补偿…

使用spring的优势

使用spring的优势 1、Spring通过DI、AOP和消除样板式代码来简化企业级Java开发 ​2、Spring框架之外还存在一个构建在核心框架之上的庞大生态圈&#xff0c;它将Spring扩展到不同的领域&#xff0c;如Web服务、REST、移动开发以及NoSQL ​3、低侵入式设计&#xff0c;代码的…

【电泳仪品牌】生科必知的电泳仪品牌

推荐阅读&#xff1a; 《利斧科学&#xff08;CLS)电泳个性化定制解决方案》 hi~大家好&#xff01;我是三三。今天和大家来分享下实验室里的那些电泳那些事儿&#xff01; 话说电泳可以说是我们实验室里很常用的主儿了&#xff01;不管是蛋白质、核酸、细胞、病毒等&#xf…

Spring的好处及特点

Spring是一个轻量级控制反转&#xff08;IOC&#xff09;和面向切面&#xff08;AOP&#xff09;的容器框架&#xff0c;它主要是为了解决企业应用开发的复杂性而诞生的。 目的:解决企业应用开发的复杂性。 功能&#xff1a;使用基本的javaBean代替EJB. 范围&#xff1a;任何的…