Spring Security 学习使用

概要:

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是用于保护基于Spring的应用程序的实际标准。

Spring Security是一个框架,致力于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring Security的真正强大之处在于可以轻松扩展以满足自定义要求

Spring Security 与 Shiro 很像,除了类不一样,名字不一样;都是做认证、授权操作。

Spring Security(安全)

在web开发中安全第一位,过滤器、拦截器、黑白名单等

安全不是功能性需求,没有考虑到安全,网站也能实现与运行;但存在用户隐私泄露,与漏洞的风险。

开发网站时:安全应该在何时考虑?设计之初就应考虑。

web系统的权限主要分为:功能权限,查看权限,菜单权限,通常实现这些权限控制一般用拦截器、过滤器操作,但是需要耗费大量资源写代码。从 mvc --> spring --> spring boot 一路在简化,所以繁琐的认证是不希望看到的,Spring Security由此诞生。

AOP:横切--配置类...

认识SpringSecurity:

Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!

记住几个类:

WebSecurityConfigurerAdapter:自定义Security策略

AuthenticationManagerBuilder:自定义认证策略

@EnableWebSecurity:开启WebSecurity模式					@Enable****   注解开启某个功能

Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。

“认证”(Authentication)

身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。

身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。

“授权” (Authorization)

授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。

这个概念是通用的,而不是只在Spring Security 中存在。

参考官网:Spring Security

查看我们自己项目中的版本,找到对应的帮助文档: #servlet-applications 8.16.4

Spring Security Reference

使用Spring Boot + Spring Security + Thymeleaf

举例操作步骤(其他成熟的例子):Spring Boot + Spring Security + Thymeleaf 举例_ThinkingInGIS的博客-CSDN博客

(1).pom.xml文件中导入如下依赖

值得注意:spring boot的版本最好在 2.0.0以上 2.0.9以下,一般用2.0.7

<!-- spring security-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--thymeleaf模板页面种使用spring security的整合包,可以去掉版本号使用-->
<dependency>
   <groupId>org.thymeleaf.extras</groupId>
   <artifactId>thymeleaf-extras-springsecurity4</artifactId>
   <version>3.0.4.RELEASE</version>
</dependency>

(2).yml文件种关闭 thymeleaf的缓存,使我们可以随时调试页面不用重启

spring:
  thymeleaf:
    cache: false  #关闭thymeleaf模板引擎的缓存,方便开发时随时调试

(3).java文件中新建一个config目录,创建spring security 配置类:SpringSecurityConfig

package com.hp.boot.config;

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

/**
 * AOP 横切 :拦截器!
 * 不用改变代码就可以执行类似拦截器的操作,比拦截器好玩多了,拦截器要大量代码功能也没这么多
 * @EnableWebSecurity 注解:打开WebSecurity
 */
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 链式编程方法
     * 授权:configure(HttpSecurity http)[设置http安全策略]
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //自定义,首页所有人可以访问,功能页只有对应有权限的人才可以访问
        //authorizeRequests认证请求,
        http.authorizeRequests()
                //antMatchers设置某一个路径,permitAll所有人可以访问
                .antMatchers("/", "/index", "/login").permitAll()
                //antMatchers设置某一个路径,hasRole某个角色的人才可以访问
                //.antMatchers("/level/**").hasRole("admin")
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2");

        //没有访问权限的,设置默认开启跳转到登陆页 http://localhost:8081/项目名/login
        //.loginPage()可以自定义formLogin登陆页面地址
        //.loginProcessingUrl()自定义登录认证请求
        //.usernameParameter()自定义登录表单提交的用户名name,.passwordParameter()自定义登录表单提交的密码name (般配合.loginProcessingUrl()一起使用)
        //使用loginPage()自定义登录页面后,登录页面的表单请求要改成.loginPage("/toLogin")中一样的路径才可以登录成功
        //使用loginProcessingUrl()自定义认证请求后,登录页面的表单请求就可以使用loginProcessingUrl()中自定义的认证请求
        //但是使用自定义认证请求后,登录提交的"用户名","密码" 的name默认名称是 "username","password";
        //如果是其他名字,则还需要使用.usernameParameter("*").passwordParameter("*") 自定义"用户名","密码"的name
        http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login");


        //防止网站攻击:get 不安全(明文传输),post可以
        //csrf(跨站请求伪造,通过一些get方式让网站收到攻击,springboot 默认开启,需要关闭)  disable()关闭
        http.csrf().disable();

        //设置开启注销,正常注销后跳转首页或登录页:使用logoutSuccessUrl方法
        //.deleteCookies("remove").invalidateHttpSession(true);删除cookie清空session
        //.logoutSuccessUrl("/**");注销成功的页面;logoutUrl("/**");注销页面
        http.logout().logoutSuccessUrl("/");

        //.rememberMe()开启登录页的记住我功能,本身是个cookie 默认保存两周
        //.rememberMeParameter()自定义登陆页表单提交时 记住我 勾选框的name名称
        //(勾选登录后用户被保存进cookie 叉掉浏览器再访问,用户还在可以直接访问;浏览器可以手动清理就失效了)
        //如果登录页是自定义的,那么提交登录时记住我这个功能的 勾选框和表单的name
        //也是需要根据需求自定义的,就需要使用.rememberMeParameter()进行自定义
        http.rememberMe().rememberMeParameter("remember");
    }

    /**
     * 认证:configure(AuthenticationManagerBuilder auth)
     * 密码编码:PasswordEncoder
     * 在Spring Security 5.0+中新增了很多加密方法
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //auth.inMemoryAuthentication()从内存中获取认证[从内存读取用户进行认证是一个特点]
        //auth.jdbcAuthentication()从数据库中获取认证[正常情况认证数据都是从数据库读取]
        //.withUser("用户名").password("密码").roles("角色1","角色2")

        //passwordEncoder(new BCryptPasswordEncoder())获取认证时进行密码编码选择加密,可以new很多种编码格式的加密
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                //withUser需要认证的用户,password认证用户的密码[new BCryptPasswordEncoder()与上面的方法同步使用进行明文密码编码转换],roles用户的角色可以是多个
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                //多个用户时,使用and()方法可以无限拼接多个用户
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }

}

(4).controller层的页面路由设计:

package com.hp.boot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PageController {



   /**
    * 测试Spring security 路径
    * @return
    */
   @RequestMapping({"/","index"})
   public String home(){
      return "index";
   }

   @RequestMapping("level1/{id}")
   public String level1(@PathVariable("id") int id){
      System.out.println(id);
      return "view/level1/"+id;
   }

   @RequestMapping("level2/{id}")
   public String level2(@PathVariable("id") int id){
      return "view/level2/"+id;
   }
}   

(5).html模板页面按照controller中路由返回的目录结构创建,如下图:

 

(6).上图中的index.html中,在页面使用 Security 控制菜单权限等...

<!DOCTYPE>
<!--sec = url = http://www.thymeleaf.org+"/"+"pom.xml导入的thymeleaf和springsecurity整合包的名称" -->
<html
        xmlns:th="http://www.thymeleaf.org"
        xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <title>Hello Thymeleaf resources</title>
</head>
<body>
<div>
    <h1>Spring Sucurity : index.html</h1>

    <!-- 登陆显示登出按钮 isAuthenticated() 判断登录-->
    <div sec:authorize="isAuthenticated()">
        用户名:<span sec:authentication="name"></span>
        角色:<span sec:authentication="principal.authorities"></span>
        <a th:href="@{/logout}">登出</a>
    </div>

    <!-- 未登陆显示登录按钮 !isAuthenticated() 判断未登录-->
    <div sec:authorize="isAuthenticated()">
        用户名:<span sec:authentication="name"></span>
        角色:<span sec:authentication="principal.authorities"></span>
        <a th:href="@{/login}">登入</a>
    </div>
    <!--菜单权限:根据用户角色控制 -->
    <ul>
        <li>首页</li>
        <li>用户</li>
        <li sec:authorize="hasRole('vip1')"><a th:href="@{/level1/1}">区域</a></li>
        <li sec:authorize="hasRole('vip2')"><a th:href="@{/level2/2}">功能</a></li>
    </ul>
</div>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值