SpringSecurity---八个小实验带你掌握最基本的使用

实验用到的模板

https://download.csdn.net/download/m2606707610/12122449

已上传,免费下载。

在上一篇博客中我已经在HelloWorld中导入了该模板,大家可以参考上篇博客,来进行这篇博客的学习。

https://blog.csdn.net/m2606707610/article/details/104099005

第三章 SpringSecurity-实验

1.实验一:授权首页和静态资源

 配置类(AppWebSecurityConfig extends WebSecurityConfigurerAdapter

     重写configure(HttpSecurity http)方法

@Configuration

@EnableWebSecurity

public class AppWebSecurityConfig extends WebSecurityConfigurerAdapter

扫描二维码关注公众号,回复: 8958383 查看本文章

@Override

protected void configure(HttpSecurity http) throws Exception {

//super.configure(http); //取消默认配置 

http.authorizeRequests()

.antMatchers("/layui/**","/index.jsp").permitAll() //设置匹配的资源放行

.anyRequest().authenticated(); //剩余任何资源必须认证

}

}

测试结果

  1. 静态资源和index.jsp都可以访问
  2. 不存在的资源或有权限但不存在的资源404

   3.无权限的资源,403访问被拒绝

             

2.实验二:默认及自定义登录页

  1. 开启formLogin()功能 ,http.formLogin()
  2. 静态资源和index.jsp都可以访问
  3. 不存在的资源
    1. http://localhost/spring-security-helloworld/xxx 重定向到登录页
    2. http://localhost:8080/springSecurityTest/login

http://localhost/spring-security-helloworld/layui/xxx  有权限时,找不到资源会报404错误

  1. 总结:默认表单登录页面的规则

1)、自动生成一个登录页

2)、登录请求被默认提交到  /login    POST下

3)、生成隐藏域,可以防重复提交和跨站请求伪造;

<input name="_csrf" type="hidden" value="755f0b3c-0965-430b-852e-dcf6c77e7edb" />

为了测试方便,先禁用这个功能: http.csrf().disable();

4)、默认提交的字段名为:name='password'  name='username'

  1. 指定登录页
    1. http.formLogin().loginPage("/index.jsp"); //去到指定的登录页
    2. 静态资源和index.jsp都可以访问
    3. 不存在的资源
      1. http://localhost/spring-security-helloworld/xxx 重定向到自定义登录页
      2. http://localhost/spring-security-helloworld/layui/xxx 404错误
http.formLogin()//开启表单登录功能
                .loginPage("/toLogin")//自定义默认登录页,这里toLogin为转向自己的登录页
                .usernameParameter("loginacct")//这里指定自定义登录页的账号name
                .passwordParameter("userpswd")//这里指定自定义登录页的密码name
                .loginProcessingUrl("/doLogin")//这指定的是自定义登录页表单提交的action,不指定则默认为/login
                .defaultSuccessUrl("/main");//登陆成功后去到哪个页面

3.3 实验三:自定义表单登录逻辑分析

  1. 表单提交地址:${PATH }/index.jsp
  2. 表单提交请求方式:post
  3. 表单提交请求失败,提取错误消息:${SPRING_SECURITY_LAST_EXCEPTION.message}
  4. 如何提交表单:
    1. 引入jquery: <script src="${PATH }/layui/jquery.min.js"></script>
    2. $("form").submit();
    3. 表单提交参数名称: username  password
  5. 提交请求被拒绝

暂时禁用csrf:http.csrf().disable();

  1. 登录逻辑分析

/**默认登录页面

   * /login GET - the login form

   * /login POST - process the credentials and if valid authenticate the user

   * /login?error GET - redirect here for failed authentication attempts

   * /login?logout GET - redirect here after successfully logging out

 

   * 定制登录页面:loginPage("/index.jsp"):规定登录页的地址在哪里

   * /index.jsp GET - the login form

   * /index.jsp POST - process the credentials and if valid authenticate the user

   * /index.jsp?error  GET - redirect here for failed authentication attempts

   * /index.jsp?logout GET - redirect here after successfully logging out

* ${SPRING_SECURITY_LAST_EXCEPTION.message}可以取出错误消息

   */

  1. 测试结果

3.4实验四:自定义认证用户信息

  1. 自定义认证用户信息
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("ADMIN")
.and()
.withUser("lisi").password("123123").authorities("USER","MANAGER");
}
  1. CSRF跨站请求伪造
  1. SpringSecurity添加了csrf功能【DefaultCsrfToken】,所有的表单提交为了防止跨站请求伪造,我们需要加上_csrf项; 或者,暂时禁用http.csrf().disable();

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

    1. ${_csrf}  ===>>>  org.springframework.security.web.csrf.DefaultCsrfToken@19116cfd
    2. <input type="hidden" name="_csrf" value="310988c2-3f9d-4651-9e19-6ef4b2c4aa3a"/>

 

  1. 如果不禁用csrf,默认是开启的状态;页面不设置csrf表单域,那么,提交登录请求会报错

  1. 令牌值变化:
    1. 如果登录成功(用户名,密码正确),令牌会被删除,
    2. 重新回到登录页后退网页,令牌会重新生成;
    3. 如果登录失败(用户名,密码错误),令牌不变。
    4. 刷新登录页,令牌值也不变
  2. 作用:  
    1. 防止别的网站伪造数据,提交请求到我们的网站。

  1. 扩展-了解XSS
  • XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。 
  • CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为XSS更具危险性

3.5实验五:用户注销完成

  1. 添加注销功能(logout)http.logout()默认规则           
  1. /logout:退出系统
  2. 如果csrf开启,必须post方式的/logout请求,表单中需要增加csrf token
  3. logoutUrl();退出系统需要发送的请求,默认为/logout
  4. logoutSuccessUrl();退出系统成功以后要跳转的页面地址
  5. addLogoutHandler():自定义注销处理器
  6. deleteCookies():指定需要删除的cookie
  7. invalidateHttpSession():session失效(DEBUG)

3.6 实验六:基于角色的访问控制

  1. 设置资源可以访问的角色

http.authorizeRequests().antMatchers("/layui/**","/index.jsp").permitAll() //允许所有人都访问静态资源,无论登录(认证)与否

.antMatchers("/level1/**").hasRole("学徒")

.antMatchers("/level2/**").hasRole("大师")

.antMatchers("/level3/**").hasRole("宗师")

.anyRequest().authenticated(); //放置最后,以上没有规定的都需要权限认证。

  1. 注意:
    1. .anyRequest().authenticated()错误的设置在前面,后面的设置就不起作用了。
    2. 设置所有,"/**"都可以访问,其他再进行的设置就不会起作用了
    3. 设置匿名访问/level3/**  可以不用登录,匿名访问:.anyRequest().anonymous();
  2. 拥有该角色的资源可以访问,否则不可以访问

auth.inMemoryAuthentication()

.withUser("zhangsan").password("123456").roles("ADMIN","学徒","宗师")

.and()

.withUser("自定义访问拒绝处理页面,lisi").password("111111").authorities("USER","MANGER");

3.7 实验七:自定义访问拒绝处理页面

  1. 直接增加处理映射界面

http.exceptionHandling().accessDeniedPage("/unauth.html");

  1. 在控制器类中增加映射处理

@RequestMapping("/unauth.html")

public String unauth(){

return "unauth";

}

  1. 增加显示页面,将main.jsp复制,命名为unauth.jsp,增加一句提示信息

<h1>你无权访问该页面...</h1>

  1. 测试显示效果

  1. 自定义异常处理器

http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {

@Override

public void handle(HttpServletRequest request, HttpServletResponse response,

AccessDeniedException accessDeniedException) throws IOException, ServletException {

request.setAttribute("message", accessDeniedException.getMessage());

request.getRequestDispatcher("/WEB-INF/views/unauth.jsp").forward(request, response);

}

});

3.8 实验八:记住我功能

3.8.1 记住我功能-免登录原理

  1. http.rememberMe();
  2. 默认规则
    1. 页面checkbox提交remember-me参数
    2. 默认记住2周登录状态:AbstractRememberMeServices

    1. 会在cookie中保存名为:remember-me的cookie
  1. 记住了以前登录的状态,以后再访问就不用登录了
  1. 登录后页面,关闭浏览器,直接访问:

http://localhost/spring-security-helloworld/main.html 可以成功访问,不必登录。

  1. 这种方式,token值是放置在内存中的,服务器端重启tomcat,token会失效。需要将token记录在数据库持久化才不会失效。

3.8.2 记住我-数据版

  1. 引入pom.xml 包

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>4.3.20.RELEASE</version>

</dependency>

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.1.12</version>

</dependency>

<!-- mysql驱动 -->

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>5.1.47</version>

</dependency>

  1. 配置数据源

<!-- 配置数据源 -->

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

<property name="username" value="root"></property>

<property name="password" value="root"></property>

<property name="url" value="jdbc:mysql://192.168.137.3:3306/security?useSSL=false"></property>

<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>

</bean> 

<!--  jdbcTemplate-->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource" ref="dataSource"></property>

</bean>

  1. 创建表

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key,token varchar(64) not null, last_used timestamp not null)

  1. 设置记住我

@Autowired

DataSource dataSource;

 

@Override

protected void configure(HttpSecurity http) throws Exception {

//。。。

//记住我

JdbcTokenRepositoryImpl ptr = new JdbcTokenRepositoryImpl();

ptr.setDataSource(dataSource);

http.rememberMe().tokenRepository(ptr);

}

 

发布了227 篇原创文章 · 获赞 77 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/m2606707610/article/details/104099005