SpringSecurity web

安全管理框架

需要依赖多

shiro 轻量

  • SSM+Shiro
  • SpringBoot/SpringCloud+SpringSecurity

配置用户名密码

  • 配置文件

  • extends WebSecurityConfigurerAdapter
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = passwordEncoder.encode("123");
auth.inMemoryAuthentication().withUser("lucy").password(password).roles("admin");
} @Bean
PasswordEncoder password() {
return new BCryptPasswordEncoder();
} }
  • 自定义实现类配置
  1. 创建配置类,设置使用哪个userDetailsService实现类
  2. 编写实现类,返回User对象,User对象有用户名密码和操作权限
  3. 自定义登录页面
@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter { @Autowired
private UserDetailsService userDetailsService; @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(password());
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//自定义登录页面
.loginPage("/login.html") //登录页面
.loginProcessingUrl("/user/login") //登录访问路径
.defaultSuccessUrl("/test/index").permitAll() //登录成功跳转
.and().authorizeRequests()
.antMatchers("/","/test/add","/user/login").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();//关闭csrf防护
} @Bean
PasswordEncoder password() {
return new BCryptPasswordEncoder();
} }
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService { @Autowired
private UsersMapper usersMapper; @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
Users users = usersMapper.selectOne(queryWrapper);
if(users == null ){
throw new UsernameNotFoundException("用户名不存在");
} //查数据库
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); // return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()),auths);
}
}

设置访问权限

.antMatchers("/test/index").hasAuthority("admins")//只有admin权限才能访问

.antMatchers("/test/index").hasAnyAuthority("admins,manager")//有其中一个权限即可访问

.antMatchers("/test/index").hasRole("sale")//为ROLE_sale

.antMatchers("/test/index").hasAnyRole("sale,customer")//多个角色的任何一个就可访问

//配置没有权限访问跳转自定义页面
http.exceptionHandling().accessDeniedPage("/unauth.html");
    @Override
protected void configure(HttpSecurity http) throws Exception {
//配置没有权限访问跳转自定义页面
http.exceptionHandling().accessDeniedPage("/unauth.html"); http.formLogin()//自定义登录页面
.loginPage("/login.html") //登录页面
.loginProcessingUrl("/user/login") //登录访问路径
.defaultSuccessUrl("/test/index").permitAll() //登录成功跳转
.and().authorizeRequests()
.antMatchers("/","/test/add","/user/login").permitAll()
.antMatchers("/test/index").hasAuthority("admins")//只有admin权限才能访问
.anyRequest().authenticated()
.and().csrf().disable();//关闭csrf防护
}

注解授权

启动类上加注解

@EnableGlobalMethodSecurity(securedEnabled = true)

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class Springsecuritydemo1Application { public static void main(String[] args) {
SpringApplication.run(Springsecuritydemo1Application.class, args);
} }

@Secured

具有某个角色可以用访问该方法

@GetMapping("update")
@Secured({"ROLE_sale","ROLE_manager"})
public String update() {
return "hello update";
}

@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)

@PreAuthorize

执行方法前校验admins

@GetMapping("update")
//@Secured({"ROLE_sale","ROLE_manager"})
@PreAuthorize("hasAnyAuthority('admins')")
public String update() {
return "hello update";
}

@PostAuthorize

执行方法后校验

@PreFilter

@PostFilter

用户注销

修改配置类protected void configure(HttpSecurity http) throws Exception加上

http.logout().logoutUrl("/logout").logoutSuccessUrl("/index/add").permitAll();

自动登录

  1. Cookie
  2. 安全框架机制实现自动登录

原理:

  1. 认证成功->浏览器cookie存加密字符串,数据库存cookie的加密串,用户信息字符串
  2. 再次访问->获取cookie信息,拿着cookie信息到数据库进行比对,如果查询到对应信息,认证成功,就可以登录。

springsecurity实现:

  • 创建表
CREATE TABLE `persistent_logins`(
`username` VARCHAR (64) NOT NULL,
`series` VARCHAR(64) NOT NULL,
`token` VARCHAR(64) NOT NULL,
`last_used` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(`series`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
  • 配置类注入数据源,配置操作数据库对象
    @Autowired
private DataSource dataSource; @Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource); //jdbcTokenRepository.setCreateTableOnStartup(true); //设置自动创建token表
return jdbcTokenRepository;
}
  • .and().rememberMe().tokenRepository(persistentTokenRepository())
    .tokenValiditySeconds(60)//设置有效时长
    .userDetailsService(userDetailsService)//设置userDetailsService操作数据库
    @Override
protected void configure(HttpSecurity http) throws Exception { //配置没有权限访问跳转自定义页面
http.exceptionHandling().accessDeniedPage("/unauth.html"); //
http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/add").permitAll(); http.formLogin()//自定义登录页面
.loginPage("/login.html") //登录页面
.loginProcessingUrl("/user/login") //登录访问路径
.defaultSuccessUrl("/success.html").permitAll() //登录成功跳转
.and().authorizeRequests()
.antMatchers("/","/test/add","/user/login").permitAll()
// .antMatchers("/test/index").hasAuthority("admins")//只有admin权限才能访问
// .antMatchers("/test/index").hasAnyAuthority("admins,manager")
//ROLE_xxx
.antMatchers("/test/index").hasRole("sale")
// .anyRequest().authenticated()
.and().rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60)//设置有效时长
.userDetailsService(userDetailsService)//设置userDetailsService操作数据库
.and().csrf().disable();//关闭csrf防护
}
  • 登录页面添加复选框 name必须为"remember-me"
<input type="checkbox" name="remember-me">自动登录

CSRF

跨站请求伪造

跨站请求攻击,简单地说,是攻击者通过一些技术手段七篇用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行

->>web中用户身份验证的一个漏洞:简单的身份验证之恶能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

实现CSRF原理:(只对"GET","HEAD","TRACE","OPTIONS"防护)

生成csrfToken保存到HttpSession,每次访问把带着过来的token和session存储的token是否一样

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
request.setAttribute(HttpServletResponse.class.getName(), response);
CsrfToken csrfToken = this.tokenRepository.loadToken(request);//创建token
boolean missingToken = csrfToken == null;
if (missingToken) {
csrfToken = this.tokenRepository.generateToken(request);
this.tokenRepository.saveToken(csrfToken, request, response);
} request.setAttribute(CsrfToken.class.getName(), csrfToken);
request.setAttribute(csrfToken.getParameterName(), csrfToken);//得到表单传递过来的token
//requireCsrfProtectionMatcher指定了防护的请求方式
if (!this.requireCsrfProtectionMatcher.matches(request)) {
filterChain.doFilter(request, response);
} else {
String actualToken = request.getHeader(csrfToken.getHeaderName());
if (actualToken == null) {
actualToken = request.getParameter(csrfToken.getParameterName());
} if (!csrfToken.getToken().equals(actualToken)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request));
} if (missingToken) {
this.accessDeniedHandler.handle(request, response, new MissingCsrfTokenException(actualToken));
} else {
this.accessDeniedHandler.handle(request, response, new InvalidCsrfTokenException(csrfToken, actualToken));
} } else {
filterChain.doFilter(request, response);
}
}
}

Spring Security微服务权限

基本概念

单点登录:一次登录其他模块能直接操作

  • 基于Session,那么Spring Security会对cookie里的sessionId进行解析,找到服务器存储的session信息,然后判断当前用户是否符合请求的要求
  • 如果是token,则是解析出token,然后将当前请求加入到SpringSecurity管理的权限信息中去

查出权限列表,存入到redis中,根据用户名生成token再放入到cookie中,在header放token,springsecurity从header获取token,从token获取用户名,根据用户名从redis获取权限列表。由springsecurity给当前与用户赋予权限,可以进行相应操作。

案例

创建工程

登录

添加角色

为角色分配菜单

添加用户分配角色

SpringSecurity基本使用的更多相关文章

  1. spring mvc 和spring security配置 spring-servlet.xml和spring-security.xml设置

    spring-servlet.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  2. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(前言)

    一直希望能够搭建一个完整的,基础Web框架,方便日后接一些外快的时候,能够省时省力,终于花了一周的时间,把这个东西搞定了.特此写下此博客,一来是纪念,二来是希望能够为别人提供方便.顺带说一下,恩,组合 ...

  3. 【JavaWeb】SSM+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(六)

    Showings 我个人的项目,当前不断地在更新. 我希望做成一个好项目,同时,也是在锻炼自己的技术. 在项目中发现问题,学习知识,是比较可取的一条路子. 这样学习到的知识,虽然分散,但是都很实用,而 ...

  4. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(五)

    SpringSecurity(2) 好久没有写了,之前只写了一半,我是一边开发一边写Blog一边上班,所以真心没有那么多时间来维护Blog,项目已经开发到编写逻辑及页面部分了,框架基本上已经搭建好不会 ...

  5. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(四)

    SpringSecurity(1) 其实啊,这部分我是最不想写的,因为最麻烦的也是这部分,真的是非常非常的麻烦.关于SpringSecurity的配置,让我折腾了好半天,网上的配置方式一大把,但总有一 ...

  6. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(一)

    Spring+MyBatis 首先要搭建的是Spring+MyBatis的整合框架,毕竟Spring是整个Web框架的核心部位,而数据库操作是一切测试的基础嘛. 目录结构 ━java ┣ contro ...

  7. SSO单点登录Spring-Security & CAS使用手册

    1.1概述 1.1.1单点登录介绍 单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可 ...

  8. spring4.2.3+mybatis+spring-security配置文件

    1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=&qu ...

  9. springmvc+spring-security+mybatis +redis +solar框架抽取

    参考文章:Spring MVC 3 深入总结: 第二章 Spring MVC入门 —— 跟开涛学SpringMVC 参考博客:http://www.cnblogs.com/liukemng/categ ...

  10. 安全框架 SpringSecurity 和 Shiro 对比

    突然再次很想理一下权限的事,但是实在不知道实际情况选哪个框架好,现在整理下网上的资料,做一下对比. 1.Spring-security 对spring 结合较好,如果项目用的springmvc ,使用 ...

随机推荐

  1. 发评测赢好礼 | Serverless 函数计算征集令

    随着云计算发展,云原生热度攀升,Serverless 架构崭露头角且发展势头迅猛.不仅被更多开发者所关注,市场占有率也逐年提高.阿里云函数计算(Function Compute)是一个事件驱动的全托管 ...

  2. ReentrantLock 公平锁源码 第0篇

    ReentrantLock 0 关于ReentrantLock的文章其实写过的,但当时写的感觉不是太好,就给删了,那为啥又要再写一遍呢 最近闲着没事想自己写个锁,然后整了几天出来后不是跑丢线程就是和没 ...

  3. EEPROM存储电路(M24C64芯片)

    电可擦写可编程只读存储器(Electrically Erasable Programmable Read-only Memory, EEPROM)实现掉电情况下保存数据,设计温湿度变送器采用M24C6 ...

  4. manjaro 安装后的基本配置

    第一步:设置官方镜像源 sudo pacman-mirrors -i -c China -m rank # 输入以上命令后会有弹出框,选择一个国内镜像(推荐 https://mirrors.ustc. ...

  5. 基于 Hexo 从零开始搭建个人博客(二)

    阅读本篇前,请先配置好相应的环境,请仔细阅读教程 基于 Hexo 从零开始搭建个人博客(一). 原文链接:基于 Hexo 从零开始搭建个人博客(二) 前言 博客搭建过程遇到任何问题,优先在本页面搜索, ...

  6. 再见Docker!Containerd安装与使用

    Containerd 的技术方向和目标 简洁的基于 gRPC 的 API 和 client library 完整的 OCI 支持(runtime 和 image spec) 同时具备稳定性和高性能的定 ...

  7. SSH远程登录:两台或多台服务器之间免密登录设置

    有两台(或多台)同局域网的服务器A:192.168.2.21,B:192.168.2.25.让A,B这两台服务器之间能两两互相免密登录,并且每台服务器都可以自我免密登录(自我免密登录即:ssh loc ...

  8. 第十天python3 函数的销毁

    全局函数销毁 三种方式: 1.重新定义同名函数 2.del语句删除函数对象 3.程序结束时 局部函数销毁 三种方式: 1.重新在上级作用域定义同名函数: 2.del语句删除函数对象: 3.上级作用域销 ...

  9. 更换可执行文件glibc版本的某一次挣扎

    0x00:前言 在做pwn的堆题时,会遇到不同版本的glibc.为此我们会装不同版本的虚拟机去应对.一般来说会装Ubuntu16和Ubuntu18虚拟机,这两个系统对应的glibc版本差别较大,且较常 ...

  10. Vue 路由的一些复杂配置

    1 # 一.路由的props参数 2 export default new VueRouter({ 3 routes:[ 4 { 5 name:'guanyu', // 命名路由 6 path:'/a ...