SpringBoot工程中Spring Security应用实践记录流程分析

网友投稿 259 2022-12-09

SpringBoot工程中Spring Security应用实践记录流程分析

目录SpringSecurity 应用简介认证授权分析SpringSecurity 架构设计快速入门实践 创建项目添加项目依赖启动服务访问测试自定义认证逻辑认证流程分析定义security配置类定义数据访问层对象定义UserDetailService接口实现类自定义登陆页面启动服务进行访问测试授权逻辑设计及实现修改授权配置类定义资源访问对象启动服务实现访问测试总结(Summary)

SpringSecurity 应用

简介

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

认证授权分析

用户在进行资源访问时,要求系统要对用户进行权限控制,其具体流程如图-1所示:

SpringSecurity 架构设计

鸟瞰SpringSecurity 基本技术架构,例如:

绿色部分是认证过滤器,需要我们自己配置,可以配置多个认证过滤器。认证过滤器可以使用 Spring Security 提供的认证过滤器,也可以自定义过滤器(例如:短信验证)。认证过滤器要在 configure(HttpSecurity http)方法中配置,没有配置不生效。下面会重点介绍以下三个过滤器:

UsernamePasswordAuthenticationFilter 过滤器:该过滤器会拦截前端提交的 POST 方式的登录表单请求,并进行身份认证。

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

ExceptionTranslationFilter 过滤器:该过滤器不需要我们配置,对于前端提交的请求会直接放行,捕获后续抛出的异常并进行处理(例如:权限访问限制)。

FilterSecurityInterceptor 过滤器:该过滤器是过滤器链的最后一个过滤器,根据资源权限配置来判断当前请求是否有权限访问对应的资源。如果访问受限会抛出相关异常,并由 ExceptionTranslationFilter 过滤器进行捕获和处理。

快速入门实践

创建项目

创建security项目,其pom.xml文件内容如下:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

spring-boot-starter-parent

org.springframework.boot

2.3.2.RELEASE

com.cy

05-security

1.0-SNAPSHOT

8

8

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

spring-boot-starter-parent

org.springframework.boot

2.3.2.RELEASE

com.cy

05-security

1.0-SNAPSHOT

8

8

添加项目依赖

第一步:创建项目,其pom.xml文件核心依赖如下:

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-security

第二步:启动服务(依赖添加以后会默认添加一个tomcat,端口8080)

服务启动之后,你会发现,控制台会出现一个随机的密码,用于访问当前系统,默认用户名是user,密码就是控制台上的密码,如图所示:

启动服务访问测试

服务启动后,打开浏览器进行访问,如图所示:

输入账号(默认用户名为user)和密码登陆成功默认为如下页面.

其中,出现这个页面表示还没有配置登陆成功页面,这个资源页面现在还不存在,可以在项目的resources目录下创建static目录(假如没有此目录),然后在此目录下创建index.html页面,内容如下:

此时,再次启动服务进行登陆,呈现登陆成功的效果,如图所示:

自定义认证逻辑

认证流程分析

定义security配置类

定义配置类,基于此类配置认证和授权逻辑,例如:

package com.cy.security.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

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.bcrypt.BCryptPasswordEncoder;

@Configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {

/**

* 认证授权管理器对用户输入的密码与数据库中存储的密码进行比对时,

* 需要对这个密码加密,加密算法需要我们自己指定

* @return

*/

@Bean

public BCryptPasswordEncoder passwordEncoder(){

return new BCryptPasswordEncoder();

}

@Override

protected void configure(HttpSecurity http) throws ExceptiLVfmPFon {

//super.configure(http);

//关闭跨域攻击

http.csrf().disable();

//自定义登陆表单

http.formLogin().loginPage("/login.html").loginProcessingUrl("/login");

//请求资源的认证配置

http.authorizeRequests()

.antMatchers("/login","/login.html")

.permitAll()

.anyRequest().authenticated();

}

}

定义数据访问层对象

定义数据访问层对象,基于此对象实现用户及用户权限信息的获取,例如:

package com.cy.security.dao;

import com.cy.security.domain.SysUser;

import org.apache.ibatis.annotations.Mapper;

import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper

public interface UserMapper {

/**

* 基于用户名获取用户信息

* @param username

* @return

*/

@Select("select id,username,password,status " +

"from tb_users " +

"where username=#{username}")

SysUser selectUserByUsername(String username);

/**

* 基于用户id查询用户权限

* @param userId 用户id

* @return 用户的权限

* 涉及到的表:tb_user_roles,tb_role_menus,tb_menus

*/

@Select("select distinct m.permission " +

"from tb_user_roles ur join tb_role_menus rm on ur.role_id=rm.role_id" +

" join tb_menus m on rm.menu_id=m.id " +

"where ur.user_id=#{userId} and m.permission is not null")

List selectUserPermissions(Long userId);

}

定义UserDetailService接口实现类

Spring Security 提供了一个UserDetailService接口,我们可以基于此接口实现类,实现用户信息的获取和封装,例如:

@Service

public class UserDetailServiceImpl implements UserDetailsService {

@Autowired

private UserMapper userMapper;

/**

* 客户端点击登陆时,添加些用户信息会传给此方法

* @param username

* @return

* @throws UsernameNotFoundException

*/

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

//1.基于用户名查询用户信息

SysUser user=userMapper.selectUserByUsername(username);

//...判断自己写...

System.out.println(user);

//2.查询用户登陆用户权限

List permissions=userMapper.selectUserPermissions(user.getId());

System.out.println(permissions);

//3.封装用户信息并返回,将用户信息交给认证管理器,认证授权管理器负责对用户输入的信息进行认证和授权

List authorityList =

AuthorityUtils.createAuthorityList(permissions.toArray(new String[]{}));

return new User(username, user.getPassword(),authorityList);

}

}

自定义登陆页面

在resources的static目录下创建login.html页面,例如:

integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

启动服务进行访问测试

授权逻辑设计及实现

修改授权配置类

在权限配置类上添加启用全局方法访问控制注解,例如

package com.cy.auth.config;

//这个配置类是配置Spring-Security的,

//prePostEnabled= true表示启动权限管理功能

@EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration

public class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter {

……

}

定义资源访问对象

package com.cy.res.controllerhttp://;

@RequestMapping("/res")

@RestController

public class ResourceController {

@PreAuthorize("hasAuthority('sys:res:view')")

@RequestMapping("/retrieve")

public String doRetrieve(){

return "select resource ok";

}

@PreAuthorize("hasAuthority('sys:res:create')")

@RequestMapping("/create")

public String doCreate(){

return "create resource";

}

}

其中,@PreAuthorize注解描述方法时,用于告诉系统访问此方法时需要进行权限检测。需要具备指定权限才可以访问。例如:

启动服务实现访问测试

打开浏览器分别输入http://localhost:8080/res/create和http://localhost:8080/res/select进行测试分析。

总结(Summary)

本章节主要是对spring security 在springboot平台下是如何使用的。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 基础之NIO 学习详解
下一篇:IntelliJ IDEA窗口组件具体操作方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~