Java SpringSecurity入门案例与基本原理详解

目录
  • 1、入门案例
    • 1.1、创建SpringBoot项目
    • 1.2、勾选对应的maven依赖
    • 1.3、编写Controller路由
    • 1.4、启动项目
  • 2、基本原理
    • 2.1、Security的本质
    • 2.2、Security装载过程(一)
    • 2.3、Security装载过程(二)
    • 2.4、UsernamePasswordAuthenticationFilter过滤器
  • 总结

1、入门案例

1.1、创建SpringBoot项目

1.2、勾选对应的maven依赖

这里一些依赖可以没有,最主要是要有Web和Security两个依赖即可!

1.3、编写Controller路由

@Controller
public class RouterController {
    @RequestMapping(value = {"/index","/","/index.html"})
    @ResponseBody
    public String success(){
        return "Hello SpringSecurity";
    }
}

1.4、启动项目

  • 启动项目之后会发现自动来到了登录页面,这个登录页面并不是我们写的,是由Security自带的并且现在说明Security已经开启了用户认证。
  • 可以在控制台拿到密码(随机),用户名为user;使用密码登录之后就能看到页面了!

2、基本原理

2.1、Security的本质

  • SpringSecurity的本质是Interceptor拦截器 + Filter过滤器的执行链,而拦截器的本质是AOP。
  • 可以在security包中看到大量的拦截器类、过滤器类等等,它们分别负责不同的功能。
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
org.springframework.security.web.context.SecurityContextPersistenceFilter
org.springframework.security.web.header.HeaderWriterFilter
org.springframework.security.web.csrf.CsrfFilter
org.springframework.security.web.authentication.logout.LogoutFilter
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter
org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter
org.springframework.security.web.savedrequest.RequestCacheAwareFilter
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
org.springframework.security.web.authentication.AnonymousAuthenticationFilter
org.springframework.security.web.session.SessionManagementFilter
org.springframework.security.web.access.ExceptionTranslationFilter
org.springframework.security.web.access.intercept.FilterSecurityInterceptor

2.2、Security装载过程(一)

  • 根据SpringBoot自动装配原理可以得知,SpringBoot在启动时会自动加载spring-boot-autoconfigure包下的spring.factories中的配置,其中有做安全认证的security组件!

  • 虽然自动装配了security的组件,但是并没有完全生效,还需要导入security的依赖,这时才会根据@Condition进行条件装配bean。其中最主要的是会装载一个DelegatingFilterProxy类。
  • DelegatingFilterProxy类的作用是将上述所有的过滤器进行串起来
// 过滤器执行链
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    Filter delegateToUse = this.delegate;
    if (delegateToUse == null) {
        synchronized(this.delegateMonitor) {
            delegateToUse = this.delegate;
            if (delegateToUse == null) {
                WebApplicationContext wac = this.findWebApplicationContext();
                if (wac == null) {
                    throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?");
                }
                delegateToUse = this.initDelegate(wac);
            }
            this.delegate = delegateToUse;
        }
    }
    this.invokeDelegate(delegateToUse, request, response, filterChain);
}
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
    String targetBeanName = this.getTargetBeanName();			//FilterChainProxy
    Assert.state(targetBeanName != null, "No target bean name set");
    Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class);
    if (this.isTargetFilterLifecycle()) {
        delegate.init(this.getFilterConfig());
    }
    return delegate;
}

2.3、Security装载过程(二)

  • initDelegate方法中的getTargetBeanName为springSecurityFilterChain,由FilterChainProxy类生成
  • 内部核心方法doFilterInternal中可以看到获取到的所有过滤器。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	....
		doFilterInternal(request, response, chain);
	....
}
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	...
	List<Filter> filters = getFilters(firewallRequest);
	...
}

一共有14个自动装配好的过滤器、拦截器

2.4、UsernamePasswordAuthenticationFilter过滤器

  • 这是Security中的一个过滤器,用户对登录/login请求进行拦截验证的实现类。
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
		throws AuthenticationException {
	if (this.postOnly && !request.getMethod().equals("POST")) {
		throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
	}
	String username = obtainUsername(request);
	username = (username != null) ? username : "";
	username = username.trim();
	String password = obtainPassword(request);
	password = (password != null) ? password : "";
	UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
	// Allow subclasses to set the "details" property
	setDetails(request, authRequest);
	return this.getAuthenticationManager().authenticate(authRequest);
}

其中核心的方法是authenticate()方法,在这里对用户提交的账号和密码进行验证。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • java SpringSecurity使用详解

    目录 SpringSecurity 1.pom.xml 简介 1.pom.xml 2.Security的controller 3.路径转发的controller 注销及权限控制 1.导入依赖thymeleof整合security 2.html命名空间 3.根据用户的登录状态进行判断显示该有的信息 4.根据源码写表单name属性 5.实现有什么权限显示什么样的信息 6.注销logout-404 总结 SpringSecurity shrio,SpringSecurity:认证,授权(VIP1,vi

  • Java开发之spring security实现基于MongoDB的认证功能

    本文实例讲述了Java开发之spring security实现基于MongoDB的认证功能.分享给大家供大家参考,具体如下: spring security对基于数据库的认证支持仅限于JDBC,而很多项目并非使用JDBC,比如Nosql数据库很多使用的是 Mongo Java Driver,这样就无法用默认的<jdbc-user-service>进行支持认证. 如果项目不是使用JDBC,没么解决办法就是:自己定义一个认证服务. 新建一个CustomUserDetailsService类 这个类

  • Spring Security拦截器引起Java CORS跨域失败的问题及解决

    在已设置CORS的项目中加入Spring Security,导致跨域访问失败,一开始以为是设置错CORS的问题,后来才发现是因为Spring Security的拦截冲突引起的. (一) CORS介绍 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制. response响应头 响应头字段名称 作用 Access-Contro

  • 详解springSecurity之java配置篇

    一 前言 本篇是springSecurity知识的入门第二篇,主要内容是如何使用java配置的方式进行配置springSeciruty,然后通过一个简单的示例自定义登陆页面,覆盖原有springSecurity默认的登陆页面:学习这篇的基础是 知识追寻者之前发布 过 的<springSecurity入门篇> 二 java配置 2.1配置账号密码 如下所示, 使用 @EnableWebSecurity 在配置类上开启security配置功能: 在配置类中定义bean 名为 UserDetails

  • java中Spring Security的实例详解

    java中Spring Security的实例详解 spring security是一个多方面的安全认证框架,提供了基于JavaEE规范的完整的安全认证解决方案.并且可以很好与目前主流的认证框架(如CAS,中央授权系统)集成.使用spring security的初衷是解决不同用户登录不同应用程序的权限问题,说到权限包括两部分:认证和授权.认证是告诉系统你是谁,授权是指知道你是谁后是否有权限访问系统(授权后一般会在服务端创建一个token,之后用这个token进行后续行为的交互). spring

  • Java SpringSecurity入门案例与基本原理详解

    目录 1.入门案例 1.1.创建SpringBoot项目 1.2.勾选对应的maven依赖 1.3.编写Controller路由 1.4.启动项目 2.基本原理 2.1.Security的本质 2.2.Security装载过程(一) 2.3.Security装载过程(二) 2.4.UsernamePasswordAuthenticationFilter过滤器 总结 1.入门案例 1.1.创建SpringBoot项目 1.2.勾选对应的maven依赖 这里一些依赖可以没有,最主要是要有Web和Se

  • Spring AOP注解案例及基本原理详解

    切面:Aspect 切面=切入点+通知.在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解.切面负责将 横切逻辑(通知) 编织 到指定的连接点中. 目标对象:Target 将要被增强的对象. 连接点:JoinPoint 可以被拦截到的程序执行点,在spring中就是类中的方法. 切入点:PointCut 需要执行拦截的方法,也就是具体实施了横切逻辑的方法.切入点的规则在spring中通过AspectJ pointcut expression language来描述.

  • Java多线程案例之定时器详解

    目录 一.什么是定时器 二.标准库中的定时器(timer) 2.1什么是定时器 2.2定时器的使用 三.实现定时器 3.1什么是定时器 3.2最终实现代码 一.什么是定时器 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码 定时器是一种实际开发中非常常用的组件,我们举几个例子: 1.比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连 2.比如一个 Map, 希望里面的某个 key 在 3s 之后过期(自动删除

  • Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

    Shiro简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理 三个核心组件:Subject, SecurityManager 和 Realms Subject代表了当前用户的安全操作 SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务. Realm充当了Shiro与应用安全数据间的"桥梁"或者"连接器&q

  • Java基础之switch分支结构详解

    一.基本语法 二.流程图 1.画出 swtich 出流程 2.案例说明流程图 三.快速入门 案例:Switch01.java 请编写一个程序,该程序可以接收一个字符,比如:a,b,c,d,e,f,g a 表示星期一,b 表示星期二 - 根据用户的输入显示相应的信息.要求使用 switch 语句完成 代码: /* 案例:Switch01.java 请编写一个程序,该程序可以接收一个字符,比如:a,b,c,d,e,f,g a表示星期一,b表示星期二 - 根据用户的输入显示相应的信息.要求使用 swi

  • java中的interface接口实例详解

     java中的interface接口实例详解 接口:Java接口是一些方法表征的集合,但是却不会在接口里实现具体的方法. java接口的特点如下: 1.java接口不能被实例化 2.java接口中声明的成员自动被设置为public,所以不存在private成员 3.java接口中不能出现方法的具体实现. 4.实现某个接口就必须要实现里面定义的所有方法. 接下来看一个实现接口的案例: package hello;   interface competer{ //定义接口 void set_comp

  • java中switch选择语句代码详解

    switch结构(开关语句)的语法 switch(表达式 ){ --->类型为int.char case 常量1 :--->case 结构可以有多个 //语句块1 break; --->程序跳出switch结构 case 常量n :--->常量的值不能相同 //语句块n break; default:--->和if结构中的 else作用相同 //语句块 break; } 下面看一段代码示例,有详细的注释,大家可以参考: public class SwitchStu{ /* s

  • Java编程Retry重试机制实例详解

    本文研究的主要是Java编程Retry重试机制实例详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下 1.业务场景 应用中需要实现一个功能: 需要将数据上传到远程存储服务,同时在返回处理成功情况下做其他操作.这个功能不复杂,分为两个步骤:第一步调用远程的Rest服务逻辑包装给处理方法返回处理结果:第二步拿到第一步结果或者捕捉异常,如果出现错误或异常实现重试上传逻辑,否则继续逻辑操作. 2.常规解决方案演化 1)try-catch-redo简单重试模式: 包装正

  • java虚拟机之JVM调优详解

    JVM常用命令行参数 1. 查看参数列表 虚拟机参数分为基本和扩展两类,在命令行中输入 JAVA_HOME\bin\java就可得到基本参数列表. 在命令行输入 JAVA_HOME\bin\java –X就可得到扩展参数列表. 2. 基本参数说明: -client,-server: 两种Java虚拟机启动方式,client模式启动比较快,但是性能和内存管理相对较差,server模式启动比较慢,但是运行性能比较高,windos上采用的是client模式,Linux采用server模式 -class

  • Java开发必备知识之数组详解

    一.ASCII码 二.为什么需要数组 案例: 160班 现在 77人 统计 全班的Java成绩 用程序进行存储 变量 统计 全班不及格的同学 要 补考 补考过的同学 修改成绩 定义 77 个变量 int 帅 = 59: int 洋 = 100: int cto = 60: int ceo = 58: 三.什么是数组 概念:数组就是内存中一块 连续的 内存空间,用于存放 相同类型 的多个数据 四.定义数组 声明一个数组:确定数组中存放的数据类型 语法: 数据类型[] 数组名://建议 数据类型 [

随机推荐