浅谈SpringSecurity基本原理

yizhihongxing

浅谈SpringSecurity基本原理

什么是SpringSecurity

SpringSecurity是一个基于Spring框架的安全框架,它提供了完善的认证(authentication)和授权(authorization)机制,可用于保护Web应用程序中的敏感资源。

SpringSecurity的基本原理

SpringSecurity的主要组件

SpringSecurity的主要组件包括:

  1. 认证安全组件(Authentication):负责验证用户身份。
  2. 授权安全组件(Authorization):负责控制用户对系统资源的访问权限。
  3. 过滤器安全组件(Filter):拦截用户请求并进行安全验证。

SpringSecurity的认证原理

SpringSecurity的认证原理基于“客户端(或用户)提供的凭据(credentials)”进行验证。凭据可以是用户名和密码、证书、OAuth令牌等。

SpringSecurity认证的大致过程如下:

  1. 应用程序拦截客户端请求,并将其传递给SpringSecurity过滤器。
  2. SpringSecurity过滤器验证客户端提供的凭据,并使用AuthenticationManager进行身份验证。
  3. AuthenticationManager返回一个被验证的Authentication对象。
  4. 如果Authentication对象不存在,则重新进行验证。否则,将Authentication对象存储在SecurityContextHolder中。
  5. 认证完成后,SpringSecurity过滤器将请求传递给应用程序处理。

SpringSecurity的授权原理

SpringSecurity的授权原理基于“访问控制列表(Access Control List,ACL)”进行控制。ACL包含资源路径、角色和权限信息。

SpringSecurity授权的大致过程如下:

  1. 应用程序在调用Controller之前,经过SpringSecurity的过滤器安全组件。
  2. SpringSecurity过滤器验证客户端的Authorization信息,并获取客户端所属的角色以及访问资源的权限。
  3. SpringSecurity根据ACL判断访问控制是否合法。
  4. 如果不合法,SpringSecurity返回拒绝访问的响应码。
  5. 如果合法,SpringSecurity将请求传递给Controller进行处理。

SpringSecurity示例1

配置SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login")
                .permitAll().and()
                .logout().permitAll()
                .and()
                .csrf().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

这里使用@EnableWebSecurity注解启用WebSecurity,重载configure(HttpSecurity http)方法,配置请求拦截规则。"/admin/**"路径需要“ADMIN”角色才能访问,其它请求需要经过认证才能访问。我们还可以对登录页面、登出操作、跨站请求伪造防护进行配置。

配置UserDetailsService

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User " + username + " not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(), getAuthorities(user));
    }

    private Collection<GrantedAuthority> getAuthorities(User user) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (Role role : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }
}

这里实现了UserDetailsService接口,重载loadUserByUsername(String username)方法,通过username查询用户,并将它的角色转换成Spring Security的角色。

运行示例

  1. 使用注解@EnableWebSecurity启用Spring Security。
  2. 配置AuthenticationManagerBuilder。
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

这里使用自定义的UserDetailsService,同时配置密码编码器BCryptPasswordEncoder。

  1. 配置控制器

在Controller中,我们使用@RequestMapping注解定义多个请求路径,用于模拟不同权限的访问控制。

@Controller
public class HomeController {
    @RequestMapping(value = {"/", "/home"})
    public String home() {
        return "home";
    }

    @RequestMapping(value = "/admin")
    public String admin() {
        return "admin";
    }

    @RequestMapping(value = "/login")
    public String login() {
        return "login";
    }

    @RequestMapping(value = "/403")
    public String error403() {
        return "403";
    }
}

示例代码已上传至GitHub:https://github.com/liaojack8/SpringSecurityDemo。

SpringSecurity示例2

继承WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN","USER");
        auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("user")).roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login").permitAll()
                .and()
                .logout().permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

这里使用内存用户存储进行模拟,并重载configure(HttpSecurity http)方法,配置请求拦截规则。

配置控制器

在Controller中,我们使用@RequestMapping注解定义多个请求路径,用于模拟不同权限的访问控制。

@Controller
public class HomeController {
    @RequestMapping(value = {"/", "/home"})
    public String home() {
        return "home";
    }

    @RequestMapping(value = "/admin")
    public String admin() {
        return "admin";
    }

    @RequestMapping(value = "/user")
    public String user() {
        return "user";
    }

    @RequestMapping(value = "/login")
    public String login() {
        return "login";
    }

    @RequestMapping(value = "/403")
    public String error403() {
        return "403";
    }
}

示例代码已上传至GitHub:https://github.com/liaojack8/SpringSecurityDemo-InMemory。

结语

通过以上两个示例,我们了解了SpringSecurity的基本原理以及如何在SpringBoot项目中进行配置和使用。同时,了解到SpringSecurity提供了多种认证和授权方式,我们可以根据实际情况进行选择和配置。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈SpringSecurity基本原理 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Sprint Boot @EnableTransactionManagement使用方法详解

    在Spring Boot中,@EnableTransactionManagement注解用于启用事务管理。使用@EnableTransactionManagement注解可以确保在使用@Transactional注解时,Spring Boot能够正确地管理事务。本文将详细介绍@EnableTransactionManagement注解的作用和使用方法,并提供…

    Java 2023年5月5日
    00
  • python、java等哪一门编程语言适合人工智能?

    针对“哪一门编程语言适合人工智能”这个问题,答案并不是非常确定。不同的编程语言和不同的开发环境都有其适用的领域。 Python是人工智能领域的主要语言之一。它拥有成熟且强大的第三方库,例如NumPy、Pandas、Matplotlib和scikit-learn等,在数据处理和分析方面非常出色。同时,Python也有很多用于深度学习的框架,例如TensorFl…

    Java 2023年5月19日
    00
  • 关于Java中对象的向上转型和向下转型

    什么是多态? 同一个类调用同一个方法会产生不同的影响/结果 这就是多态 public class Pet{ public void eat(){ System.out.println(“Pet eat…”) } } class Dog extends Pet{ public void eat(){ System.out.pringln(“Dog eat.…

    Java 2023年4月22日
    00
  • 详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    Spring的两种代理方式 在使用Spring框架时,我们常常会使用到AOP(面向切面编程)的相关技术,而代理是AOP中必不可少的一个环节。在Spring中,支持两种代理方式:JDK动态代理和CGLIB动态代理。这两种代理方式都有各自的特点和优劣,具体使用哪种方式则要根据具体的情况而定。 JDK动态代理 JDK动态代理是基于接口的代理,它要求目标对象必须实现…

    Java 2023年5月20日
    00
  • 详解Spring Boot实战之Rest接口开发及数据库基本操作

    下面为您详细讲解“详解Spring Boot实战之Rest接口开发及数据库基本操作”的完整攻略。 1. 背景介绍 在Web开发中,RESTful API是一种非常流行的架构风格,它能够提供简单、易用、灵活的接口服务。而Spring Boot作为一个现代化的Java Web框架,则能够非常好地实现RESTful API的开发。 本攻略将为您介绍如何使用Spri…

    Java 2023年5月19日
    00
  • Springboot打包成jar发布的操作方法

    请允许我来详细讲解“Springboot打包成jar发布的操作方法”的完整攻略。 一、前置条件 Java开发环境已经配置好。 Maven已经安装配置好。 已经使用Springboot完成了应用程序的开发。 二、打包Springboot应用程序 1. 使用命令行 运行下面的命令将应用程序打包成可执行的jar包: mvn clean package 该命令会在M…

    Java 2023年5月19日
    00
  • Eclipse使用maven搭建spring mvc图文教程

    下面是关于Eclipse使用Maven搭建Spring MVC的完整攻略,包含两个示例说明。 Eclipse使用Maven搭建Spring MVC图文教程 Spring MVC是一个流行的Java Web框架,它可以帮助我们快速构建Web应用程序。在本文中,我们将介绍如何使用Eclipse和Maven搭建Spring MVC应用程序。 步骤1:创建Maven…

    Java 2023年5月17日
    00
  • 如何进行Java压力测试?

    作为网站的作者,您想进行Java应用程序的压力测试以确保应用程序的性能能够满足用户期望和要求。在这里,我们将提供一个完整的Java应用程序压力测试攻略,它将使您了解压力测试的概念,不同类型的测试以及如何开始执行压力测试。下面是一个详细的步骤: 1.准备测试环境和工具 要执行Java应用程序的压力测试,您需要准备一个测试环境。这意味着您需要一个测试计划,例如一…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部