序:本文主要参考 spring实战 对里面的知识做一个梳理
1.Spring Security介绍
Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别
处理身份证验证和授权.它充分使用了依赖注入和面向切面的技术.
Spring security主要是从两个方面解决安全性问题:
2.Web请求级别的保护
对于请求级别的安全性来说,主要时通过保护一个或多个URL,使得只有特定的用户才能访问,并其他用户访问该URL的内容.本文主要是基于spring mvc下整合Spring security模块.
2.1 声明代理Servlet过滤器
在web中的URL的一般需要过滤器进行保护,所以需要借助一系列的Servlet过滤器提供各种各样的安全性功能.这也需要在web.xml中配置一系列相关的
1 <filter> 2 <filter-name>springSecurityFilterChainfilter-name> 3 <filter-class> 4 org.springframework.web.filter.DelegatingFilterProxy 5 filter-class> 6 filter>
DelegatingFilterProxy是一个代理的Servelt过滤器,它主要负责将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个
springSecurityFilterChain,也可称为FilterChainProxy.它可以链接任意多个其他的过滤器,根据这些过滤器提供不同的安全特性.但是你并不需要在spring配置文件中配置该过滤器的bean和它所链接的其他过滤器.
2.2 配置最小化web安全性和拦截请求
1 <http auto-config="true"> 2 <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> 3 http>
在spring的配置文件中加入这段代码可以拦截站点/admin分支行下的所有URL请求.并限制只有具备"ROLE_ADMIN"权限的用户才可以访问,"ROLE_ADMIN"是自定义的一个权限.pattern默认使用的是Ant格式。如果需要使用正则表达式则在http 元素的path-type设置为regex。
<http> <form-login /> <http-basic/> <logout /> <intercept pattern="/**" access="ROLE_DEMO" /> http>
Spring security 3.0以后加入了对SpEL的支持,可以将
<http auto-config="true" use-expressions="true"> .. <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"> http>
Spring Security 支持的所有SpEL表达式如下:
安全表达式 | 计算结果 |
authentication | 用户认证对象 |
denyAll | 结果始终为false |
hasAnyRole(list of roles) | 如果用户被授权指定的任意权限,结果为true |
hasRole(role) | 如果用户被授予了指定的权限,结果 为true |
hasIpAddress(IP Adress) | 用户地址 |
isAnonymous() | 是否为匿名用户 |
isAuthenticated() | 不是匿名用户 |
isFullyAuthenticated | 不是匿名也不是remember-me认证 |
isRemberMe() | remember-me认证 |
permitAll | 始终true |
principal | 用户主要信息对象 |
2.3 通过表单安全登陆
虽然
<http auto-config="true"> <from-login login-processing-url="/static/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"> http>
在自定义的登录界面中将表单提交地址设置为"/static/j_spring_security_check",同时需要将用户名输入框和密码输入框name分别设置为j_username和j_password 。有些应用中往往会设置记住密码,方便用户访问应用,不需要每次都登录。实现该功能只需要在
<remember-me key="spitterKey" token-validity-seconds="2419200"/>
静态页面中加入:
<input name="_spring_security_rember_me" type="checkbox"/>
2.4 强制请求使用https
https传输数据比较安全,如将用户,密码提交可以使用https保证数据传输的安全。可以进行以下设置,保证每次对指定URL请求,Spring Security都会自动重定向为https请求。不管用户访问时是否加入https.
<intercept pattern="/admin/**" access="ROLE_DEMO" requires-channel="https" />
3. 保护视图
Spring Security提供jsp标签库,支持视图级别的保护,这个标签库包含3个标签:
3.
Hello <security:authentication property="principal.usrname" var="loginId" scope="request"> <security:authorize access="hasRole('ROLE_ADMIN')"> 如果当前用户有ROLE_ADMIN权限,则显示这部分内容 security:authorize>
<security:authorize url="/admin/**"> 如果当前用户有/admin/**对应的权限,则显示这部分内容 security:authorize>
4.认证用户 前面提到很多用户对象和用户权限的问题,他们的关系和定义就是通过认证用户来定义的。 Spring Security提供了以下认证策略:
这里主要是介绍基于spirng配置和jdbc的。
4.1 配置内存用户存储库
首先建立一个用户服务,配置所有用户和权限信息。然后交给认证管理器管理,认证管理器会将认证的任务交给一个或多个认证提供者。
<user-service id="userService"> <user name="alibaba" password="123456" authorities="ROLE_ADMIN"> <user name="baidu" password="66666" authorities="ROLE_BAIDU"> ...... user-service> <authentication-manager> <authentication-provider user-service-ref="userService"/> authentication-manager>
另一种方式将认证提供者和用户服务装配在一起,适用于只有一种用户服务:
<authentication-provider> <user-service id="userService"> <user name="alibaba" password="123456" authorities="ROLE_ADMIN"> <user name="baidu" password="66666" authorities="ROLE_BAIDU"> ...... user-service> authentication-provider>
4.2 基于数据库进行认证
这个是最常用的是用户认证,因为很多应用都是采用数据库存储用户数据。Spring Security提供了
<jdbc-user-service id="userService" data-source-ref="dataSource" users-by-username="select username,password, true from user where username=?" authories-by-username-query="select username,role from user_role where username=?" /> <authentication-manager> <authentication-provider user-service-ref="userService"/> authentication-manager>
5.保护方法调用
spring security的方法级别的保护是基于Spring AOP技术。首先需要在spring配置文件中加以下配置,才能使spring Security保护那些使用相关注解的方法。
<global-method-security secured-annotations="enabled" />
spring Security支持4种方法级别安全性的方法:
5.1 @Secured和 @RelosAllowed
@Secured("ROLE_ADMIN") public void addUser(User user){ ... } @RolesAllowed("ROLE_ADMIN") public void updateUser(User user){ ... }
5.2 使用Spring 方法调用前和调用后注解方法
可以使用SpEL方法有四种:
5.3 匹配一个或多个明确声明的切点方法
为多个方法设置相同的授权检查,spring security提供了
<global-method-security secured-annotations="enabled" > <protect-pointcut access="ROLE_ADMIN" expression="execution(@com.securitytest.service.UserService**.*(String)" >