SpringSecurity原理(一)——初探

原创
05/07 14:05
阅读数 96

简介

SpringSecurity原理(一)——初探 SpringSecurity原理(二)——认证 SpringSecurity原理(三)——授权 SpringSecurity原理(四)——过滤器 SpringSecurity原理(五)——扩展与配置

之前使用Shiro的时候觉得有些繁琐,最近开始用Spring Security的时候才发现和Spring Security一比,Shiro简直对新手太友好了。

主要是Spring Security架构虽然比较清晰,但是它考虑的问题太多了,简单的说就是Spring Security为我们准备了大而全的解决方案。

而很多时候,可能我们并不需要那么全面的解决方案。几个简单的例子,一个用户认证,很可能我们只需要用户名和密码就够用了。

但是Spring Security中设计得更像是Linux的用户系统,考虑了用户过期、用户禁用、用户密码过期等等,最重要的是没有给默认的实现,必须自己重写我们不需要的方法,虽然并不是什么难事,但是总有点不得劲,具体可以看org.springframework.security.core.userdetails.UserDetails接口。

Spring Security虽然繁杂,但是整个的架构还是比较清晰,下面我们就来简单看一看Spring Security的原理。

前置知识

Spring Security主要是服务于Web应用,Spring Security也主要是通过Java的Filter来实现。

Java的Web应用两大核心就是:

  1. Servlet
  2. Filter

很多朋友可能已经忘了在没有SpringMVC之前被java的web.xml配置支配的恐惧。

如果对此没有印象的朋友,或者完全没有使用过的朋友,可以看下面的web.xml配置回忆一下,看还能不能记得每个配置的含义。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>terrible</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <filter>
        <display-name>EcodingFilter</display-name>
        <filter-name>EcodingFilter</filter-name>
        <filter-class>vip.mycollege.filter.EnCodeFilter</filter-class>
        <init-param>
            <param-name>EncodeCoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>EcodingFilter</filter-name>
        <servlet-name>hello</servlet-name>
        <url-pattern>*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class></servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

上面的配置还是只是一个简单的Servet和一个Filter。

Java Web的整个流程还简单,就是Servelt容器,也就是Java Web服务器,如,Tomcat、Jetty等启动的时候回去加载web.xml文件,解析里面的配置,主要是Servlet和Filter,把url和Servlet、Filter对应上,这样当接收都一个url请求的时候,就交个对应的Filter和Servlet去处理。

先Filter后Servlet的,Filter可以有多个,是链式结构,有优先级。

web.xml配置方式的最大的问题就是,url映射配置复杂,稍不小心就404。

后来有了SpringMVC就好了一些,只需要配置一个Servlet,都交给org.springframework.web.servlet.DispatcherServlet这个Servlet统一处理url的映射分发,Spring自己去解析Controller注解,把url和对应的方法对应,不用自己去配置url映射了。

再后来有了SpringBoot,简直就起飞了,DispatcherServlet都不需要配置了,开箱即用。

虽然,不需要手动配置了,原理还是要了解一点,这里我们只需要记住,Java的Web请求都是要先过Filter的,而这是Spring Security施展身手的地方。

简单的示例

如果一上来就直接说一下抽象概念,很多朋友可能就放弃治疗了。所以,我们先来一个简单的入门级示例,在门口看一下Spring Security是个啥东西。

项目结构

pom依赖

首先,要引入Spring Security依赖,如果使用SpringBoot,引入非常简单

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/>
    </parent>
    <groupId>vip.oschool</groupId>
    <artifactId>spsecurity</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spsecurity</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <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>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

配置文件

server:
  port: 8081

spring:
    security:
      user:
        name: tim
        password: 111111

上面配置了一个用户tim,密码是111111,如果不配置,Spring Security会使用默认用户,每次会生成随机密码。

控制器

添加一个简单的控制器

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/index")
public class IndexController {

    @RequestMapping("/hello")
    public String hello(){
        return "Hello World";
    }
}

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StartApplication {

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

登录界面

启动之后,直接访问:http://localhost:8081/index/hello

然后,就会被重定向到:http://localhost:8081/login

登录页面

需要输入用户名和密码,这个过程有一个专有名词叫:认证,Authentication

文档

Spring Security官方文档

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部