手把手教你spring security入门

1. spring security概念

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

2. 权限控制术语概念

认证:系统对访问的身份进行验证,确定身份是否能够访问系统,可以类比于现实生活中的小区管理,只有属于该小区的业主才能进入小区,认证就相当于是一个大门,只有认证通过的身份才能访问系统。
权限:验证身份是否能够访问资源,即拥有访问资源的权限,可以类比于生活中的小区管理,只有属于该小区的业主才能进入小区,但是进入小区后是否能进入某个单元,可以认为是否有进入某个单元的权限

3. spring security应用场景

Spring Security 正是 Spring 家族中的成员,Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案,广泛应用于后台管理框架中权限管理认证和授权

4. 需求描述

现在用一个简单的系统,里面有订单的新增、删除、修改、查看功能,现在想对访问系统的身份进行认证和授权管理,实现若果是admin账号登录,怎可以访问订单管理的所有功能;如果是userAdd账号登录,则只能访问新增和查看订单功能

5. 如何使用spring security实现权限控制(需求)

5.1依赖引入

在maven的pom文件中引入spring security依赖(一旦引入了依赖,即对系统添加了需要认证的功能,即访问系统需要进行登录)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

5.2添加spring security 配置类

配置的的作用有三:
作用一:通过注解开启过滤器链过滤功能(@EnableWebSecurity)
作用二:添加认证的用户和权限,重写com.yf.config.SecurityConfig#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)方法
作用单:配置拦截资源的规则,重写com.yf.config.SecurityConfig#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)方法

package com.yf.config;

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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @projectName: springboot-security
 * @package: com.yf.config
 * @className: SecurityConfig
 * @author: yangfeng
 * @description: spring-security配置类
 * @date: 2022/11/23 15:26
 * @version: 1.0
 */
//将该配置类交给spring容器管理
@Component
//开启过滤器链对请求的拦截
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    /**
     * @Author yangfeng
     * @Description //配置认证用户信息
     *              //配置认证用户的权限
     * @Date 15:46 2022/11/23
     * @param auth:
     * @return void
     * authentication 认证:检查并确认身份,确定身份是否能通过系统的第一道大门
     **/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        auth.inMemoryAuthentication().withUser("admin").password("123456").authorities("addOrder","showOrder","updateOrder","deleteOrder");
        auth.inMemoryAuthentication().withUser("userAdd").password("123456").authorities("showOrder","addOrder");

    }
    /**
     * @Author yangfeng
     * @Description //配置拦截请求资源
     * @Date 15:46 2022/11/23
     * @param http:
     * @return void
     * authorize:批准、许可、授权的意思,检查并确定身份是否有访问特定资源的权限
     **/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeRequests()
                .antMatchers("/showOrder").hasAnyAuthority("showOrder")
                .antMatchers("/addOrder").hasAnyAuthority("addOrder")
                .antMatchers("/updateOrder").hasAnyAuthority("updateOrder")
                .antMatchers("/deleteOrder").hasAnyAuthority("deleteOrder")
                .antMatchers("/**").fullyAuthenticated().and().formLogin();

    }

    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
    
    
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }

}

5.2.1认证方法核心剖析

在这里插入图片描述

5.2.2授权方法核心剖析

在这里插入图片描述

6.权限不足(403)时跳转到自定义的页面

在项目中添加服务器参数配置信息类,定义不同情况的请求路径


package com.yf.config;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
/**
 * @Author yangfeng
 * @Description // Web 服务器参数配置,可以配置默认错误页面
 * @Date 14:42 2022/11/24
 **/
@Configuration
public class WebServerAutoConfiguration {
    
    
	@Bean
	public ConfigurableServletWebServerFactory webServerFactory() {
    
    
		TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
		//如果请求出现不同情况的异常状态,则转发到不同的异常处理路径
		ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
		ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
		ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
		ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
		ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
		ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
		factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
		return factory;
	}
}

在ErrorController中定义403转发的页面路径

package com.yf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ErrorController {
    
    

	// 403权限不足页面
	@RequestMapping("/error/403")
	public String error() {
    
    
		System.out.println("403异常处理");
		return "/error/403";
	}

}

这样在用户权限不足的情况下就会跳转到/error/403页面

7.替换框架内置的登录页面为自定义登录页面

在com.yf.config.SecurityConfig配置类中的资源拦截方法中指定登录页面的路径
在这里插入图片描述
在对应的Controller中定义/login路径最终转发的页面地址
com.yf.controller.OrderController#login,在本节代码实例中,我们是在OrderController中定义login转发的路径定义到最终登录的页面

// 自定义登陆页面
	@GetMapping("/login")
	public String login() {
    
    
		return "login";
	}

8.登录成功和登录失败的判断

在项目中定义登录成功的handler处理类,实现AuthenticationSuccessHandler接口,处理登录成功后处理的逻辑

package com.yf.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

// 认证成功
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    
    

	public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication arg2)
			throws IOException, ServletException {
    
    
		System.out.println("用户认证成功");
		res.sendRedirect("/");
	}

}

同理定义登录失败handler处理类,实现AuthenticationFailureHandler接口,在登录失败的方法中添加自己的处理逻辑

package com.yf.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

//认证失败
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    
    

	public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth)
			throws IOException, ServletException {
    
    
		System.out.println("登陆失败!");
		res.sendRedirect("https://www.baidu.com");

	}

}

在配置类的资源拦截方法中加入注入登录成功和登录失败的handler
在这里插入图片描述
在资源拦截方法中添加对应的handler
在这里插入图片描述
完整代码参考请移步链接: github代码库

猜你喜欢

转载自blog.csdn.net/yangfenggh/article/details/128007641