spring boot 基础 spring security 权限验证
一、spring security 介绍
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
二、准备
环境:jdk 1.8 、spring boot 2.0 、spring security 5.2
IDE:idea
三、创建项目
这里我们直接使用idea 来创建项目,点击file 选择new project 创建spring boot 项目 勾选web和security模块 如图所示
3.1 项目创建完成结果图如下:
3.2 在pom中导入依赖
导入security 依赖 为了方便测试我们顺便导入thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
在application.properties 文件中加入以下代码 去除html5 标签验证
#设置不要缓存 spring.thymeleaf.cache=false spring.thymeleaf.mode=LEGACYHTML5
3.3 设置配置文件
创建一个SecurityDemoConfig 类继承WebSecurityConfigurerAdapter 并在类上面添加@Configuration @EnableWebSecurity
注解标记配置信息 重写 configure 方法
package com.px.security.security;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @Author: px
* @Date: 2018/11/02 9:55
* @Version 1.0
*/
@Configuration
@EnableWebSecurity
public class SecurityDemoConfig extends WebSecurityConfigurerAdapter {
/**
* http 安全验证
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("**/css/**","**/images/**","**/img/**","*/js/**","*/plugins/**","/user/register")
.permitAll()
.and()
.formLogin()
.loginPage("/loginAdmin")
.loginProcessingUrl("/login")
//登录成功 默认跳转url
.defaultSuccessUrl("/admin")
.successForwardUrl("/admin")
//登录失败跳转url
.failureUrl("/loginAdmin")
.permitAll()
.and()
.csrf().disable()
//frame 拒绝请求问题
.headers()
.frameOptions()
.disable()
//登出相关
.and()
.logout()
//注销跳转url
.logoutSuccessUrl("/loginAdmin")
.permitAll()
//设置过期时间
.and().rememberMe().tokenValiditySeconds(200000);
}
/**
* 身份验证处理器
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
/**
* web 安全验证
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
}
设置进入admin 路径下的需要管理ADMIN 权限才能进入
//配置admin 下的都需要 ADMIN 权限才能进入 .antMatchers("/admin/**") .hasRole("ADMIN")
.formLogin() .loginPage("/loginAdmin") //设置登录页面 .loginProcessingUrl("/login") //登录 表单提交Action //登录成功 默认跳转url .defaultSuccessUrl("/admin") .successForwardUrl("/admin") //登录失败跳转url .failureUrl("/loginAdmin") .permitAll() //标记登录界面都能访问
3.4 准备测试页面
创建login.html 页面很简单 注意一点 这里的action 要和你前面在SecurityDemoConfig 配置的一致
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录界面</title>
</head>
<body>
<form method="post" action="/login">
<p>用户名<input name="username"></p>
<p>密码<input type="password" name="password" /></p>
<p><input type="submit" value="登 录"/></p>
</form>
</body>
</html>
创建登录之后的界面 home.html 内容很简单 就一个欢迎语
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>管理员界面</title>
</head>
<body>
<h1>欢迎进入管理员界面</h1>
</body>
</html>
创建controller
package com.px.security.security;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Author: px
* @Date: 2018/11/2 16:45
* @Version 1.0
*/
@Controller
public class HomeController {
@RequestMapping("/loginAdmin")
public String loginAdmin()
{
return "login";
}
@RequestMapping("/admin")
public String index()
{
return "admin/home";
}
}
四、 测试
以上步骤完成之后一个简单的权限验证已经完成了
准备测试
为了方便我们在 application 配置一个用户名 并且给他赋予ADMIN权限
#配置security 用户名密码 spring.security.user.name=admin spring.security.user.password=123456 spring.security.user.roles=ADMIN
在浏览器输入
会自动跳转到登录界面
登录之后成功跳转到home界面 说明成功了
这里我们演示 用户名是写到配置文件中的 实际开发一般是从数据库中读取的
如果要从其他渠道获取用户权限 我们要自定义UserDetaisService 进行权限验证 实现 loadUserByUsername方法即可
如果要动态配置url 路径对应的权限 需要完成自定义实现以下步骤
权限资源 SecurityMetadataSource 实现 FilterInvocationSecurityMetadataSource 接口
权限决策 AccessDecisionManager 实现AccessDecisionManager 接口
在config文件中装载bean 对象
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
public <O extends FilterSecurityInterceptor> O postProcess(
O fsi) {
fsi.setSecurityMetadataSource(mySecurityMetadataSource());
fsi.setAccessDecisionManager(myAccessDecisionManager());
return fsi;
}
});