java SpringSecurity使用详解

yizhihongxing

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日

相关文章

  • Java实现redis分布式锁的三种方式

    Java实现redis分布式锁的三种方式 在分布式系统中,实现分布式锁是很重要的一个需求。Redis作为一个内存数据库,具有高性能、高可用、操作简便等优点,因此被广泛应用于实现分布式锁。 本文将介绍Java实现redis分布式锁的三种方式:使用Redis的setnx命令、使用Lua脚本实现乐观锁、使用Redisson(一个流行的Redis客户端)实现分布式锁…

    Java 2023年5月20日
    00
  • spring data jpa 查询自定义字段,转换为自定义实体方式

    下面是详细的“spring data jpa 查询自定义字段,转换为自定义实体方式”的攻略, 自定义实体类的创建 首先,我们需要手动创建一个自定义实体类来存储查询结果: public class CustomEntity { private Long id; private String name; public CustomEntity(Long id, …

    Java 2023年5月20日
    00
  • JAVA JNI原理详细介绍及简单实例代码

    先来介绍一下什么是JNI。 JNI,全称为Java Native Interface,即Java本地接口,是一个开发工具包,提供了一种使Java代码和本地代码(C、C++等)交互的机制。 开发者可以使用JNI将本地的代码嵌入到Java应用程序中,从而充分发挥本地代码的性能,是Java与本地代码的桥梁。 下面我来分步骤详细讲解“JAVA JNI原理详细介绍及简…

    Java 2023年5月23日
    00
  • Spring事务失效场景原理及解决方案

    Spring事务失效场景原理及解决方案 原理 Spring事务使用AOP实现,核心原理是在程序执行前后动态代理,在方法执行前开启一个事务,在方法执行后根据方法执行结果决定事务是提交还是回滚。但是在以下场景中,Spring事务可能失效: 在事务方法外部调用另一个事务方法时,当前事务被挂起,新的事务启动,第二个事务抛出异常回滚,当前事务并不会回滚。 在catch…

    Java 2023年5月20日
    00
  • SpringSecurity框架简介及与shiro特点对比

    SpringSecurity框架简介及与shiro特点对比 1. Spring Security框架简介 Spring Security是一个基于Spring框架的安全框架,它提供了声明式的安全访问控制解决方案,支持基于Role的访问控制、基于ACL的访问控制,以及对Web应用安全的全面支持。 Spring Security可以轻松地与Spring框架集成,…

    Java 2023年5月20日
    00
  • java中封装JDBC工具类的实例分析

    我来为你详细讲解“Java中封装JDBC工具类的实例分析”的完整攻略。 什么是JDBC工具类 在Java中使用JDBC技术与数据库进行连接时,需要编写一些重复性较高的代码,如加载驱动、获取连接、关闭连接等。为了避免重复代码的编写,可以将这些代码封装在一个工具类中。这个工具类我们称之为JDBC工具类。 JDBC工具类的编写 加载驱动 在编写JDBC工具类的时候…

    Java 2023年6月16日
    00
  • 什么是 JVM 性能分析工具?

    以下是关于 JVM 性能分析工具的完整使用攻略: 什么是 JVM 性能分析工具? JVM 性能分析工具是用来分析 Java 程序在 JVM 上的性能表现的工具。通过使用 JVM 性能分析工具,可以找出程序中的性能瓶颈,优化程序的性能,提高程序的运行效率。 常见的 JVM 性能分析工具包括以下几种: 1. JConsole JConsole 是 JDK 自带的…

    Java 2023年5月12日
    00
  • struts中动态方法调用使用通配符

    在Struts框架中,可以通过动态方法调用使用通配符的方式,实现对请求URL的自动解析,从而找到对应的Action类及其方法进行处理。 以下是使用通配符的完整攻略: 1. 配置struts.xml 在struts.xml中,可以配置动态方法调用的命名空间及通配符等参数。如下所示: <package name="example" na…

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