Spring Security学习笔记(一)
简单说明
Spring Security,这是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。
Apache Shiro同样是Java的一个安全框架,Shiro功能相对简单一点,同样使用也简单。在这里不对谁优谁劣做评价。历史会有结论的。
Hello Word
下面来搭建一个Spring Security的HelloWord(用户信息写在配置中,没使用数据库):搭建hello有三步:首先创建编写登录相关页面、然后编写spring Security的配置文件(xml)、最后在web.xml中添加Security的配置
security可以自动生成一个简陋的登录页面、这个在配置中可以设置、下面在说怎么设置:我们就先使用它生成的页面吧。
那就跳过第一步,直接编写Security的配置文件:
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!--需要放开对该页面的过滤 否则会产生循环重定向的问题 -->
<security:http pattern="/login.jsp" security="none" />
<!-- 配置security过滤路径 -->
<security:http auto-config="true" use-expressions="true">
<!-- 配置security过滤路径 access为所需的权限-->
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<!-- 登录表单信息 登录页面 信息校验失败后转发的路径 成功后的路径(注:在这里设置使用自己的登录页面,并可以设置登录的用户名的表单name值等) -->
<!-- <security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?erro=true" default-target-url="/hahaha.jsp"/> -->
<!-- 关闭对token的验证 不关闭的话 在表单中添加 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> -->
<security:csrf disabled="true"/>
</security:http>
<!-- 在这里设置用户信息 包括对应权限 -->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="user" authorities="ROLE_USER"/>
<security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
编写完Spring security配置文件,编写web.xml如下:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>TestSpringSecurity02</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--Spring的ApplicationContext 载入-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ================spring mvc 适配器================ -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/application_springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,classpath:spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
说明
Spring security这个东西必须依赖于spring,所以在web.xml中可以看到Spring 的配置,关于spring的搭建这里不多说。到这,这个入门就算完事了,很简单。启动服务器后访问项目的根目录,可以看到security生成的登录页面,填写正确的用户信息。
登录成功后会跳转到你本来的目标页面,但是可以 在security:form-login标签中添加always-use-default-target="true" default-target-url="/abc.jsp" 表示总是使用这个默认的地址,
在实验这个入门项目的时候遇到了一个问题,访问不到index.html,是spring的配置问题。在这里记录一下。
需要注意的一点是,spring security 3.x 默认的登录拦截URL是/j_spring_security_check,而spring security 4.x默认拦截的URL是/login
form-login属性详解
form-login是spring security命名空间配置登录相关信息的标签,它包含如下属性:1. login-page 自定义登录页url,默认为/login
2. login-processing-url 登录请求拦截的url,也就是form表单提交时指定的action
3. default-target-url 默认登录成功后跳转的url
4. always-use-default-target 是否总是使用默认的登录成功后跳转url
5. authentication-failure-url 登录失败后跳转的url
6. username-parameter 用户名的请求字段 默认为userName
7. password-parameter 密码的请求字段 默认为password
8. authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
9. authentication-success-forward-url 用于authentication-failure-handler-ref
10. authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
11. authentication-failure-forward-url 用于authentication-failure-handler-ref
12. authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
关于退出
下面在说说退出登录:用户退出登录实质是使当前登录用户的session失效的操作。一般来说,用户退出后,将会被重定向到站点的非安全保护页,比如登录页面.logout 属性详解
1、logout-url LogoutFilter要读取的url,也就是指定spring security拦截的注销url
2、logout-success-url 用户退出后要被重定向的url
3、invalidate-session 默认为true,用户在退出后Http session失效
4、success-handler-ref 对一个LogoutSuccessHandler的引用,用来自定义退出成功后的操作
这里需要注意的一点是,spring security 3.x默认的注销拦截url为/j_spring_security_logout,而4.x则默认使用/logout
spring security在实现注销功能时,大致流程如下
1. 使得HTTP session失效(如果invalidate-session属性被设置为true);
2. 清除SecurityContex(真正使得用户退出)
3. 将页面重定向至logout-success-url指明的URL。
Remember-me功能
下面说说Remember-me功能。这个功能允许一个再次访问的用户在不需要输入用户名密码的情况下就可以自动登录。
实现这个功能需要两步:在页面上添加自动登录的input框、在Spring Security的xml文件中添加该功能配置。一:在页面上添加<input id="remember-me" name="remember-me" type="checkbox" checked="checked"/>自动登录
二:在xml的http标签下中添加 <remember-me key="authorition"/>
配置完这两步,使用Spring Security完成自动登录的功能就基本完成了。
在登录时选中自动登录、登录成功后会在浏览器添加一个cookie:remember-me
remember-me属性详解
remember-me属性是spring security命名空间中实现自动登录的专属配置项,它有如下属性
1. key:这个”key”属性用来辨别分辨不同项目的cookie
2. authentication-success-handler-ref 指向一个AuthenticationSuccessHandler
3. data-source-ref 指向一个DataSource数据源
4. remember-me-cookie:cookie存放的名称.默认为’remember-me’.
5. remember-me-parameter:触发自动登录的请求参数名称.默认为’remember-me’.
6. services-alias:声明一个内部定义的RememberMeServices的bean的别名,提供给程序的其他bean使用
7. services-ref:指向一个RememberMeServices,可以自定义实现自己的自动登录逻辑
8. token-repository-ref:指向一个PersistentTokenRepository bean,用来实现持久化令牌的自动登录
9. token-validity-seconds:cookie存在的时间周期,单位为秒
10. use-secure-cookie:是否设置”secure”标志,具体使用不详
11. user-service-ref:指向一个UserDetailsService的bean