java SpringSecurity使用详解

Java Spring Security使用详解

什么是Spring Security?

Spring Security是Spring框架中一个强大的安全管理框架。它提供了一个全面而灵活的安全管理机制,可以让你轻松地管理应用程序中的身份验证、授权和其他安全相关的一切。

Spring Security 的核心概念

Authentication(认证)

Authentication(认证)是指验证用户是否是合法用户的过程。常用的认证方式有用户名密码验证、证书认证、Token认证、OpenID认证等。Authentication(认证)完成之后,系统将会给这个用户颁发一个唯一的授权Token,也就是以后访问时的凭证。

Authorization(授权)

Authorization(授权)是指验证某个已认证用户是否有权进行某个操作或者访问某个资源的过程。常用的授权方式有:基本授权、角色授权、资源授权和基于表达式的授权等。

FilterChain(过滤器链)

FilterChain是指一系列过滤器的集合。在Spring Security中,FilterChain主要是由一些过滤器和Spring Security的过滤器链实现的。整个过滤器链起到的作用类似于Servlet Filter,依次对请求进行预处理和处理,并且可以决定是否将请求继续交给下一个过滤器处理。

SecurityContext(安全上下文)

SecurityContext是指当前用户的安全上下文环境,是一个容器,主要存储了当前用户的身份验证信息及授权信息等。

Spring Security 集成步骤

  1. 添加Spring Security依赖

    xml
    <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.5.0</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.5.0</version>
    </dependency>

  2. 配置Spring Security

配置文件参考代码:

``` java
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Autowired
   private UserDetailsServiceImpl userDetailsService;

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

   @Override
   public void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
   }

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

}
```

这里的配置代码示例中,我们禁用了跨站点请求伪造(CSRF)保护,允许所有用户访问根页(/)及其子集(/home)和静态资源(/css/和/js/),限制只有角色为ADMIN的用户才能访问/admin路径下的页面,而其他请求需要进行身份认证,最后配置默认的登录页面为/login,退出功能为默认。

  1. 自定义UserDetailsService

UserDetailsService是Spring Security中的一个核心接口,提供了从数据源中读取用户信息的方法。我们需要自定义实现该接口中的loadUserByUsername方法,并将其注入到Spring Security中。

实现代码参考:

``` java
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

   @Autowired
   private IUserService userService;

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       User user = userService.findByName(username);
       if (user == null) {
           throw new UsernameNotFoundException("用户名不存在:" + username);
       }
       List<GrantedAuthority> authorities = new ArrayList<>();
       if (user.getRole() != null) {
           authorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
       }
       return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), authorities);
   }

}
```

在该自定义的UserDetailsService实现代码中,我们查询数据库中的用户信息和角色信息,并通过SimpleGrantedAuthority创建GrantedAuthority列表,最后创建Spring Security中内置的User对象返回。

  1. 配置Spring Security 对静态资源的访问权限

    静态资源是指一些HTML、CSS、JS等文件,这些文件不需要通过Spring MVC来进行响应,而是直接由Web服务器进行响应的。当我们使用Spring Security时,需要对这些静态资源进行访问控制。

    注册对静态资源的安全过滤器:

    ``` java
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private CustomResourceSecurityInterceptor customResourceSecurityInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customResourceSecurityInterceptor)
                .addPathPatterns("/css/**", "/js/**");
    }
    

    }
    ```

    注册安全拦截器:

    ``` java
    @Component
    public class CustomResourceSecurityInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        boolean isAllow = false;
        if (request.getRequestURI().startsWith("/css/") || request.getRequestURI().startsWith("/js/")) {
            isAllow = true;
        }
        if (!isAllow) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
        return isAllow;
    }
    

    }
    ```

    所有的静态资源都保存在了Web项目的根目录下的/css/和/js/目录下面,根据这样一个规则,我们便可以通过request.getReuqestURI()判断出来该请求是不是静态资源,从而进行拦截处理。我们可以根据自己实际的应用场景,对相关代码进行调整和完善。

示例1:基于HTTP Basic认证的实现

HTTP Basic认证是基于用户名和密码进行简单的身份验证。

示例代码:

@EnableWebSecurity
public class HttpBasicSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/hello").authenticated()
                .anyRequest().permitAll()
                .and()
                .httpBasic();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
                .and()
                .withUser("admin").password(passwordEncoder().encode("password")).roles("ADMIN");
    }

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

在这里,我们加入了两个用户(user和admin),并给了他们不同的角色。这里我们使用了BCryptPasswordEncoder加密算法对用户的密码进行了加密。而且我们定义了访问/hello路径的所有请求都需要经过身份验证才能访问。

示例2:基于表单登录认证的实现

表单登录认证是指用户在登录时输入用户名和密码进行身份验证。

示例代码:

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class FormAuthenticationConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

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

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

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

在这里,我们通过@EnableGlobalMethodSecurity(securedEnabled = true)开启了secured的注解支持。并且还添加了登录页面的路径为"/login",和退出的路径为"/logout"。

这两个示例代码展示了如何在Spring Security中实现基本认证方式和表单登录认证,两个示例有着显著的差别,但是目的都是达到同一个目标:安全控制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java SpringSecurity使用详解 - Python技术站

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

相关文章

  • MyBatis5中Spring集成MyBatis事物管理

    下面是关于MyBatis5中Spring集成MyBatis事物管理的完整攻略: 1、引入依赖 首先需要在pom.xml文件中引入MyBatis和Spring的依赖,具体如下: <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</…

    Java 2023年5月20日
    00
  • XML简介

    XML简介 XML(可扩展标记语言)是一种用于描述文档内容的标记语言,它使用标签来标识文档中各个部分的含义,并通过这些标记实现对文档内容的组织、表示和传输。相较于 HTML 等文档语言,XML 更加通用灵活,可以应用于各种场景。 XML 基础结构 XML 文档由各种元素构成,每个元素包含一个标记和一个值(也称为“内容”或“文本”)。标记用来表示该元素的类型和…

    Java 2023年5月26日
    00
  • PHP:微信小程序 微信支付服务端集成实例详解及源码下载

    PHP:微信小程序微信支付服务端集成实例详解 在本文中,我们将为大家讲解如何在 PHP 中集成微信支付服务端,并包含了两个具体的示例。 准备工作 在开始集成之前,需要完成以下准备工作: 注册微信支付账号 在微信支付后台配置公众号或小程序,并设置回调地址 安装 curl 扩展 集成微信支付服务端 首先,我们需要在 PHP 代码中引用微信支付 SDK,可以使用 …

    Java 2023年5月23日
    00
  • java.lang.NoClassDefFoundError错误解决办法

    下面我将详细讲解如何解决”java.lang.NoClassDefFoundError”错误。 1. 什么是”java.lang.NoClassDefFoundError”错误 “java.lang.NoClassDefFoundError”错误是Java程序编译或运行过程中遇到的一个常见错误,表示无法找到相关类的定义。它通常是由以下原因导致的: 缺少相关类…

    Java 2023年5月20日
    00
  • 用java生成html文件实现原理及代码

    生成HTML文件的实现原理: 要实现用Java程序生成HTML文件,需要使用Java IO和字符串操作技术。生成HTML文件的步骤如下: 创建一个文本文件,并给定后缀名为“.html”; 在文件中编写HTML代码; 使用Java IO将HTML代码写入到创建的文本文件中; Java代码示例1: import java.io.FileWriter; impor…

    Java 2023年5月26日
    00
  • 详解Mybatis的分页插件

    MyBatis是一款非常流行的ORM框架,它在开发过程中会遇到分页查询的需求。MyBatis原生不支持分页功能,因此需要使用MyBatis的分页插件。下面是详解MyBatis的分页插件的攻略。 1. 安装分页插件 在MyBatis项目中,添加分页插件是很简单的,只需两步即可: 在pom.xml中添加分页插件的依赖: <dependency> &l…

    Java 2023年5月20日
    00
  • Java解决代码重复的三个绝招分享

    下面是详细讲解“Java解决代码重复的三个绝招分享”的完整攻略。 一、引言 在Java编程中,我们经常遇到相似但又稍有不同的代码块,这时候如果直接复制粘贴,就会导致代码冗余和可维护性下降。而Java编程的目标之一就是要写出清晰且易于维护的代码。那么我们该如何有效地解决重复代码呢? 二、使用继承 重复的代码通常是由于相似的功能需求带来的。通过分析这些功能需求,…

    Java 2023年5月30日
    00
  • 防止未登录用户操作—基于struts2拦截器的简单实现

    防止未登录用户操作是常见的Web应用程序的安全性需求之一。基于struts2拦截器可以方便地实现这一功能。接下来,我将详细讲解如何基于struts2拦截器实现防止未登录用户操作的功能。 步骤一:创建Session监听器 在Java Web应用程序中,每个会话都关联一个HTTP会话(Session)。Session监听器可以在会话开始和结束时执行操作,我们可以…

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