Spring学习笔记之Spring Security
来源:互联网 发布:苹果电脑ui设计软件 编辑:程序博客网 时间:2024/06/06 17:02
1.简介
Spring Security是为基于spring的应用程序提供声明式安全保护的安全性框架。它能够在Web请求级别和方法调用级别处理身份认证和授权。
1.1Spring Security模块
Spring Security被分成11个模块
应用程序的类路径下至少要包含Core和Configuration这两个模块。
1.2 过滤Web请求
使用Spring Security,只需要在Servlet上下文配置一个Filter——DelegatingFilterProxy就可以,这是一个特殊的Servlet Filter,它本身所做的工作并不多。只是将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个<bean>
注册在Spring应用上下文中。下面是两种配置方式:
XML:在web.xml中
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter>
Java配置:创建一个扩展的新类
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer{}
1.3简单的配置
Java配置:
任何实现了WebSecurityConfigure的类都可以用来配置Spring Security。更简单的方式是扩展WebSecurityConfigure的一个实现类WebSecurityConfigurerAdapter。
@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter{}
如果你的应用是使用Spring MVC开发的,可以使用@EnableWebMvcSecurity来替换:
@Configuration@EnableWebMvcSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter{}
具体的配置可以通过重写WebSecurityConfigurerAdapter的configure()方法来实现,下面是三个方法的功能:
下面是几个示例:
1.配置用户存储,这里使用基于内存的用户存储,此外,它还支持基于数据库表认证、基于LDAP进行认证以及自定义的用户服务(提供一个自定义的UserDetailsService接口实现。)
/** * 配置用户存储 */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //使用内存配置用户存储 auth.inMemoryAuthentication() .withUser("xuexiaoqiang").password("123").roles("USER").and() .withUser("admin").password("admin").roles("USER","ADMIN");//添加了两个用户并配置了用户角色权限 //使用以JDBC为支撑的用户存储// auth.jdbcAuthentication()// .dataSource(dataSource)// .usersByUsernameQuery(// "select username, password, true " + // "from Spitter where username=?")//重写查询语句// .authoritiesByUsernameQuery(// "select username, 'ROLE_USER' from Spitter where username=?")// .passwordEncoder(new StandardPasswordEncoder("53cr3t"));//指定密码转换器 }
2.指定哪些请求需要认证,哪些请求不需要认证,以及所需要的权限:
/** * 请求控制 */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/me").authenticated() //对路径“/me”的请求需要进行认证 .antMatchers(HttpMethod.GET, "/index").hasAuthority("ROLE_ADMIN") //对路径“/index”下的get请求需要ADMIN权限 .anyRequest().permitAll()//其他的所有请求不需要认证 .and() .requiresChannel() .regexMatchers("/form").requiresSecure()//只要是对"/form"的请求,Spring Security都视为需要安全通道并自动将请求重定向到HTTPS上。 .antMatchers("/").requiresInsecure();//对“/”的访问用HTTP通道 //http.csrf().disable();//禁用CSRF防护功能 //启用默认的登录页 http.formLogin(); //启用remember me功能 http.rememberMe() .tokenValiditySeconds(2419200)//指定token生命周期 .key("testKey");//私钥 //退出后重定向到其他页面,默认是返回登录页 http.logout() .logoutSuccessUrl("/") .logoutUrl("/signout");//重写LogoutFilter拦截路径,默认为/logout } //这里的ant指的是ant风格的通配符,regexMatchers()则是正则风格的通配符
除了authenticated() 和permitAll(),AuthorizedUrl还有下面的方法用来定义如何保护路径的配置方法
配置的规则是将最为具体的请求路径放在前面,而最不具体的路径(如antRequest())放在最后面。否则的话,不具体的路径配置将会覆盖掉更为具体的路径配置。
上面提到了access方法,它可以使用spEL表达式进行访问控制
Spring Security通过一些安全性相关的表达式扩展了Spring表达式语言
spELl的特点就是可以对各种控制进行自由的搭配,比如下面这个
http.authorizeRequests() .regexMatchers("/*") .access("hasRole('ROLE_ADMIN') and hasIpAddress('192.168.1.2')");
强制通道:
使用requiresChannel()方法能够为各种URL模式声明所要求的通道。
防止跨站请求伪造——CSRF:
Spring Security通过一个同步token的方式来实现CSRF防护的功能。
这意味着在应用中所有的表单必须在一个“_csrf”域中提交token,而且这个token必须要与服务器端计算并存储的token一致,这样的话当表单提交的时候,才能进行匹配。
下面是使用不同的模板时使用csrf的方式:
Thymeleaf:在action属性添加Thymeleaf命名空间前缀,下面的th:,就会自动生成一个“_csrf”隐藏域。
<form method="POST" th:action="@{/websecurity}">
JSP:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
如果使用Spring的表单绑定标签的话<sf:form>
标签会自动为我们添加隐藏的CSRF token标签。
下面是Spring Security默认的登录页面,里面就有“_csrf”隐藏域以及token。
<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'> <h3>Login with Username and Password</h3> <form name='f' action='/websecurity/login' method='POST'> <table> <tr> <td>User:</td> <td><input type='text' name='username' value=''></td> </tr> <tr> <td>Password:</td> <td><input type='password' name='password' /></td> </tr> <tr> <td><input type='checkbox' name='remember-me' /></td> <td>Remember me on this computer.</td> </tr> <tr> <td colspan='2'><input name="submit" type="submit" value="Login" /></td> </tr> <input name="_csrf" type="hidden" value="bdd0204e-c2d4-45b9-a11c-6e6b080d243c" /> </table> </form></body></html>
Remember-me:
默认情况下,这个功能是通过在cookie中存储一个token完成的,这个token最多两周有效。
存储在cookie中的token包含用户名,密码,过期时间,和一个私钥——在写入cookie前都进行了MD5哈希。
启用了Remember-me功能后,我们只需要在登录表单中增加这样一个复选框就可以了,不用写value值,如果被选中的话,会发送一个“on”过去:
<input type="checkbox" name="remember-me" id="remember-me" />
这是那个cookie:
2.保护视图内容
Spring Security本身提供了一个JSP标签库,而Thymeleaf通过特定的方言实现了与Spring Security的集成。
2.1 Spring Security的JSP标签库
声明:
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
使用这个标签库要记得加依赖:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.2.RELEASE</version> </dependency>
<security:accesscontrollist>
如果用户通过访问控制列表授予了指定的权限,那么渲染该标签体重的内容 <security:authentication>
渲染当前用户认证对象的详细信息 <security:authorize>
如果用户被授予了特定的权限或者SpEL表达式的计算结果为true,那么渲染该标签体中的内容例如:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%><%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body> <h1>My Name is <security:authentication property="principal.username"/></h1> <!-- 赋值给一个变量 --> <security:authentication property="principal.password" var="password" scope="request"/> <!-- 条件性的渲染内容 --> <security:authorize access="hasRole('ROLE_ADMIN')"> <h1>哈哈哈,这里只有具有ADMIN权限的用户才能看到</h1> </security:authorize></body></html>
使用<security:authentication>
JSP标签来访问用户的认证详情
2.2使用Thymeleaf的Spring Security方言
Thymeleaf的安全方言提供了与Spring Security标签库相对应的属性:
<security:authentication>
security:authorize 基于表达式的计算结果,条件性的渲染内容。类似于Spring Security的<security:authorize>
security:authorize-acl 基于表达式的计算结果,条件下的渲染内容。类似于<security:accesscontrollist>
security:authorize-expr security:auhorize属性的别名 security:authorize-url 基于给定URL路径相关的安全规则,条件性的渲染内容。类似于<security:authorize/>
标签使用url属性时的场景。为了使用安全方言,需要确保Thymeleaf Extras Spring Security已经位于应用的类路径下。然后,还需要在配置中使用SpringTemplateEngine来注册SpringSecurityDialect:
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> ... <property name="additionalDialects"> <set> <!-- Note the package would change to 'springsecurity3' if you are using that version --> <bean class="org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect"/> </set> </property> ... </bean>
然后再模板中声明命名空间:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:security="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">...</html>
然后就可以使用了:
<div th:text="${#authentication.name}"> The value of the "name" property of the authentication object should appear here. </div><div th:if="${#authorization.expression('hasRole(''ROLE_ADMIN'')')}"> This will only be displayed if authenticated user has role ROLE_ADMIN. </div>
- Spring学习笔记之Spring Security
- spring security学习笔记
- Spring Security学习笔记
- spring security学习笔记
- Spring Security学习笔记
- Spring Security学习笔记
- Spring Security学习笔记
- spring security 学习笔记
- Spring Security学习笔记
- Spring Security学习笔记之整体配置
- Spring Security学习笔记之LogoutFilter
- Spring Security学习笔记之UsernamePasswordAuthenticationFilter, ConcurrentSessionFilter
- Spring Security学习笔记之RememberMeAuthenticationFilter
- Spring Security学习笔记之ChannelProcessingFilter
- Spring Security学习笔记之SessionManagementFilter
- Spring Security学习笔记之整体配置
- Spring Security学习笔记之UsernamePasswordAuthenticationFilter, ConcurrentSessionFilter
- <学习笔记>Spring Security 学习
- 表达式求值(栈(操作数栈+操作符栈))
- 斗地主AI算法——第六章の牌型判断
- lightOj 1341Aladdin and the Flying Carpet 算数基本定理
- OSTU 最佳全局阈值处理-最大类间方差法
- docker时间校正
- Spring学习笔记之Spring Security
- 返回引用的意义 作用 未完成
- Sudoku(模拟)
- 剑指offer-18.二叉树的镜像
- davinci_u-boot_env.txt
- 【Java学习20170426】Servlet
- 没时间解释了,快上车!AngularJs入门第一讲:AngularJs入门。
- vue2.0的变化,与vue1.0对比
- TensorFlow reuse=True BasicRNNCell