java编程SpringSecurity入门原理及应用简介

目录
  • 1. SpringSecurity 框架简介
    • 1.1 概要
    • 1.2 组成以及同款产品(shiro)对比
      • 1.2.1 Spring Security
      • 1.2.2 Shiro
    • 1.3 模块划分
    • 1.4 SpringSecurity 基本原理
    • 1.5.UserDetailsService 接口讲解
  • 2.SpringSecurity Web 权限方案
    • 2.1设置登录系统的账号密码(三种方式)
      • 设计数据库表
      • 建立springboot项目,勾选相应依赖
      • 完整pom.xml
      • 数据库配置
      • 创建对应的实体类
      • 创建service层
      • 配置spring security
      • security配置类说明
  • 3.security-记住我-的实现
  • 4.用户注销功能实现
  • 5.关于CSRF
  • 6.spring security原理总结

1. SpringSecurity 框架简介

1.1 概要

正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”(或者访问控制),一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分,这两点也是 Spring Security 重要核心功能。

(1) 用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。通俗点说就是系统认为用户是否能登录

(2) 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。通俗点讲就是系统判断用户是否有权限去做某些事情。

1.2 组成以及同款产品(shiro)对比

1.2.1 Spring Security

SpringSecurity 特点:

  • 和 Spring 无缝整合。
  • 全面的权限控制。
  • 专门为Web 开发而设计。
  • 旧版本不能脱离Web 环境使用。
  • 新版本对整个框架进行了分层抽取,分成了核心模块和Web 模块。单独引入核心模块就可以脱离Web 环境。
  • 重量级。

1.2.2 Shiro

Apache 旗下的轻量级权限控制框架。

特点:

  • 轻量级。Shiro 主张的理念是把复杂的事情变简单。针对对性能有更高要求的互联网应用有更好表现。
  • 通用性。

好处:不局限于Web 环境,可以脱离Web 环境使用。
缺陷:在Web 环境下一些特定的需求需要手动编写代码定制。

Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展了多年了,但是使用的并不多,安全管理这个领域,一直是 Shiro 的天下。

相对于 Shiro,在 SSM 中整合 Spring Security 都是比较麻烦的操作,所以,SpringSecurity 虽然功能比 Shiro 强大,但是使用反而没有 Shiro 多(Shiro 虽然功能没有Spring Security 多,但是对于大部分项目而言,Shiro 也够用了)。

自从有了 Spring Boot 之后,Spring Boot 对于 Spring Security 提供了自动化配置方案,可以使用更少的配置来使用 Spring Security。

因此,一般来说,常见的安全管理技术栈的组合是这样的:

SSM + Shiro
Spring Boot/Spring Cloud + Spring Security

以上只是一个推荐的组合而已,如果单纯从技术上来说,无论怎么组合,都是可以运行的。

1.3 模块划分

1.4 SpringSecurity 基本原理

SpringSecurity 本质是一个过滤器链: 从启动是可以获取到过滤器链:

代码底层流程:重点看三个过滤器:
FilterSecurityInterceptor:是一个方法级的权限过滤器, 基本位于过滤链的最底部。

1.5.UserDetailsService 接口讲解

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

2.SpringSecurity Web 权限方案

2.1设置登录系统的账号密码(三种方式)

一:在application.xml中自行配置

spring.security.user.name = xxx
spring.security.user.password = xxx

二:编写类实现接口

三:实现数据库认证来完成用户登录
这里就拿一个例子来完成认证和授权

设计数据库表

建立springboot项目,勾选相应依赖

完整pom.xml

<?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.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

数据库配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: xxxxxx
    url: jdbc:mysql://xxxxxxxxxx //根据自己情况填写

创建对应的实体类

package com.example.demo.domain;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class User implements UserDetails {
    private Integer id;
    private String username;
    private String password;
    private Boolean enabled;
    private Boolean locked;
    private List<Role> roles;
    @Override
    // 实体类和SpringSecurity转换
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }
    @Override
    public String getPassword() {
        return null;
    }
    @Override
    public String getUsername() {
        return null;
    }
    @Override
    public boolean isAccountNonExpired() {
        return false;
    }
    @Override
    public boolean isAccountNonLocked() {
        return false;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }
    @Override
    public boolean isEnabled() {
        return false;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Boolean getEnabled() {
        return enabled;
    }
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
    public Boolean getLocked() {
        return locked;
    }
    public void setLocked(Boolean locked) {
        this.locked = locked;
    }
    public List<Role> getRoles() {
        return roles;
    }
    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
}
package com.example.demo.domain;
public class Role {
    private Integer id;
    private String name;
    private String nameZh;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getNameZh() {
        return nameZh;
    }
    public void setNameZh(String nameZh) {
        this.nameZh = nameZh;
    }
}

创建service层

package com.example.demo.mapper;
import com.example.demo.domain.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.graalvm.compiler.nodeinfo.StructuralInput;
import org.springframework.security.core.userdetails.User;
import java.util.List;
@Mapper
public interface UserMapper {
    @Select("select * from user where username=#{username}")
    public User loadUserByUsername(String username);
    @Select("select * from role r, user_role ur where r.id = ur.rid and ur.uid = #{id}")
    public List<Role> getUserRoleByUid(Integer id);
}

配置spring security

package com.example.demo.config;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configurable
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userService;
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login").permitAll()
                .and()
                .csrf().disable();
    }
}

security配置类说明

3.security-记住我-的实现

在security配置类中开启remember me功能,并设置有效期。默认时间为两周。

4.用户注销功能实现

通过退出按钮找到映射地址,在配置类中添加退出映射地址

5.关于CSRF

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click
attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web 中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

从 Spring Security 4.0 开始,默认情况下会启用CSRF 保护,以防止CSRF 攻击应用程序,Spring Security CSRF 会针对 PATCH,POST,PUT 和DELETE 方法进行防护。

6.spring security原理总结

SpringSecurity 采用的是责任链的设计模式,它有一条很长的过滤器链。

现在对这条过滤器链的 15 个过滤器进行说明:

(1) WebAsyncManagerIntegrationFilter:将 Security 上下文与 Spring Web 中用于处理异步请求映射的 WebAsyncManager 进行集成。

(2) SecurityContextPersistenceFilter:在每次请求处理之前将该请求相关的安全上下文信息加载到 SecurityContextHolder 中,然后在该次请求处理完成之后,将
SecurityContextHolder 中关于这次请求的信息存储到一个“仓储”中,然后将
SecurityContextHolder 中的信息清除,例如在 Session 中维护一个用户的安全信息就是这个过滤器处理的。

(3) HeaderWriterFilter:用于将头信息加入响应中。

(4) CsrfFilter:用于处理跨站请求伪造。

(5) LogoutFilter:用于处理退出登录。

(6) UsernamePasswordAuthenticationFilter:用于处理基于表单的登录请求,从表单中获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个过滤器的 usernameParameter 和 passwordParameter 两个参数的值进行修改。

(7) DefaultLoginPageGeneratingFilter:如果没有配置登录页面,那系统初始化时就会配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面。

(8) BasicAuthenticationFilter:检测和处理 http basic 认证。

(9) RequestCacheAwareFilter:用来处理请求的缓存。

(10) SecurityContextHolderAwareRequestFilter:主要是包装请求对象 request。

(11) AnonymousAuthenticationFilter:检测 SecurityContextHolder 中是否存在
Authentication 对象,如果不存在为其提供一个匿名 Authentication。

(12) SessionManagementFilter:管理 session 的过滤器

(13) ExceptionTranslationFilter:处理 AccessDeniedException 和
AuthenticationException 异常。

(14) FilterSecurityInterceptor:可以看做过滤器链的出口。

(15) RememberMeAuthenticationFilter:当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的 remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启。

以上就是java编程入门SpringSecurity原理及应用简介的详细内容,更多关于java编程SpringSecurity简介的资料请关注我们其它相关文章!

(0)

相关推荐

  • 手把手带你入门 Spring Security的具体流程

    Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展了多年了,但是使用的并不多,安全管理这个领域,一直是 Shiro 的天下. 相对于 Shiro,在 SSM/SSH 中整合 Spring Security 都是比较麻烦的操作,所以,Spring Security 虽然功能比 Shiro 强大,但是使用反而没有 Shiro 多(Shiro 虽然功能没有 Spring Security

  • springsecurity 基本使用详解

    最近开始学习了springsecurity框架,为写后台页面做个权限管理什么的打基础. springsecurity是基础springboot的,所以创建一个springboot工程引入依赖就可以很轻松的整合springsecurity了.(类似的权限管理框架还有shiro) 1. 创建一个普通的springboot项目(不用勾选任何东西),我这边使用的springboot版本是2.2.1.RELEASE 依赖如下: pom.xml <dependencies> <!--spring w

  • 浅谈SpringSecurity基本原理

    一.SpringSecurity 本质 SpringSecurity 本质是一个过滤器链: 从启动是可以获取到(加载)过滤器链,当执行请求时就会执行相应的过滤器: org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter org.springframework.security.web.context.SecurityContextPersistenceFilter org.sp

  • Spring Security 安全框架应用原理解析

    Spring Security 简介 背景分析 企业中数据是最重要的资源,对于这些数据而言,有些可以直接匿名访问,有些只能登录以后才能访问,还有一些你登录成功以后,权限不够也不能访问.总之这些规则都是保护系统资源不被破坏的一种手段.几乎每个系统中都需要这样的措施对数据(资源)进行保护.我们通常会通过软件技术对这样业务进行具体的设计和实现.早期没有统一的标准,每个系统都有自己独立的设计实现,但是对于这个业务又是一个共性,后续市场上就基于共享做了具体的落地实现,例如Spring Security,A

  • 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 Security的简单使用

    什么是Spring Security Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架.它实际上是保护基于spring的应用程序的标准. Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权.与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求 在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证.HTTP 表单验证.HTTP 摘要认证.OpenI

  • 浅谈spring security入门

    一 介绍 本节给知识追寻者给大家带来的是springSecurity入门篇,主要是简述下springSecrurity的启动原理和简单的入门搭建: 二 核心模块介绍 spring-security-core : 包含核心身份验证和access-contol类和接口,远程支持和基本配置AP: spring-security-web: web , url登陆验证和访问控制: spring-security-config: 支持xml 或者java注解配置: 当然其模块远不止这些,比如CAS,ALC,

  • java编程SpringSecurity入门原理及应用简介

    目录 1. SpringSecurity 框架简介 1.1 概要 1.2 组成以及同款产品(shiro)对比 1.2.1 Spring Security 1.2.2 Shiro 1.3 模块划分 1.4 SpringSecurity 基本原理 1.5.UserDetailsService 接口讲解 2.SpringSecurity Web 权限方案 2.1设置登录系统的账号密码(三种方式) 设计数据库表 建立springboot项目,勾选相应依赖 完整pom.xml 数据库配置 创建对应的实体类

  • java编程Reference核心原理示例源码分析

    带着问题,看源码针对性会更强一点.印象会更深刻.并且效果也会更好.所以我先卖个关子,提两个问题(没准下次跳槽时就被问到). 我们可以用ByteBuffer的allocateDirect方法,申请一块堆外内存创建一个DirectByteBuffer对象,然后利用它去操作堆外内存.这些申请完的堆外内存,我们可以回收吗?可以的话是通过什么样的机制回收的? 大家应该都知道WeakHashMap可以用来实现内存相对敏感的本地缓存,为什么WeakHashMap合适这种业务场景,其内部实现会做什么特殊处理呢?

  • java编程FinalReference与Finalizer原理示例详解

    之前写了一篇java编程Reference核心原理示例源码分析的文章,但由于篇幅和时间的原因没有给出FinalReference和Finalizer的分析.同时也没有说明为什么建议不要重写Object#finalize方法(实际上JDK9已经将Object#finalize方法标记为Deprecated).将文章转发到perfma社区后,社区便有同学提出一个有意思的问题?"Object#finalize如果在执行的时候当前对象又被重新赋值,那下次GC就不会再执行finalize方法了,这是为什么

  • Java编程Iterator迭代器设计原理及实现代码示例

    我们知道迭代器(Iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素.那么Iterator迭代器的设计原理是什么呢?迭代器问什么定义了一个借口,而不是一个类呢? 我们假设迭代器迭代数据的功能定义为了一个类,那么,会有这样的问题.不同的集合,由于数据结构不一样,所以他们的存储方式也是不一样的.也就是说,迭代器获取的时候,获取的方式是变化的,也就是不固定的.所以把这种方式定义为具体的实现是不合理的. 无论何种集合,他们肯定都有获取的功能,而且不知道什么时候就没有数据了.所有他

  • 深入理解Java编程线程池的实现原理

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以通过线程池来达到这样的效果.今天我们就来详细讲解一下Java的线程池,首先我们从最核心的ThreadPoolExecutor类中的方法讲起,

  • Java编程反射机制用法入门与实例总结

    本文实例讲述了Java编程反射机制用法.分享给大家供大家参考,具体如下: 前言:反射:动态获取类 (字节码文件 如本篇中的Person.class),并对其成员进行运行.反射在Android应用层的开发中可能遇到会稍微少一点,但对于想打通底层的小伙伴来说,必须要熟练掌握运用. 实体类 Person.java package com.sunwenou.reflect;// 包名 public class Person { private String name; private int age;

  • Java多线程并发编程和锁原理解析

    这篇文章主要介绍了Java多线程并发编程和锁原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等方案后,问题得到解决. 加锁方案见下文. 二.乐观锁 & 悲观锁 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁

  • Java网络编程之入门篇

    目录 一.网络基础 二.网络协议 URL类 一.网络基础 二.网络协议 实现TCP的网络编程 例子1:客户端发送信息给服务端,服务端将数据显示在控制台上 public class TCPTest1 { //客户端 @Test public void client() { Socket socket = null; OutputStream os = null; try { //1.创建Socket对象,指明服务器端的ip和端口号 InetAddress inet = InetAddress.ge

  • 入门到精通Java SSO单点登录原理详解

    目录 1. 基础概念 2. 单点登录 3. CAS 流程 4. OAuth 流程 5. CAS和OAuth的区别 1. 基础概念 SSO单点登录(Single sign-on) 所谓单点登录就是在多个应用系统中,用户只需登录一次就可以访问所有相互信任的系统. CAS 中央认证服务(Central Authentication Service) CAS是由美国耶鲁大学发起的一个企业级开源项目,旨在为WEB应用系统提供一种可靠的单点登录解决方案(WEB SSO). OAuth2.0 开放授权(Ope

  • Java中SpringSecurity密码错误5次锁定用户的实现方法

    Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 下面看下实例代码: 第

随机推荐