Spring security3
最近一直在学习spring security3,试着搭建了环境:
- 构建maven环境
项目配置pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.github.humeng126</groupId>
<artifactId>security-07</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging> <name>security-07</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springsecurity.version>3.2.3.RELEASE</springsecurity.version>
<spring.version>4.0.3.RELEASE</spring.version>
<mysql-connector.version>5.1.30</mysql-connector.version>
</properties> <dependencies>
<!-- web begin -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- web end --> <!-- spring begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<!-- spring end --> <!-- security begin -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<!-- security end --> <!-- pool begin -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- pool end --> <!-- connector begin -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
<!-- connector end --> <!-- test begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- test end --> <!-- cache begin -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.9</version>
</dependency>
<!-- cache end -->
</dependencies>
</project>
- 在web.xml配置文件增加filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>security-01</display-name> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param> <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> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> </web-app>
- spring的applicationContext.xml增加权限配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- 声明在xml中使用Spring Security提供的命名空间 -->
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans" 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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd"> <!-- 注意这个custom-filter标签,它表示将filterSecurityInterceptor放在框架原来的FILTER_SECURITY_INTERCEPTOR过滤器之前,
这样我们的过滤器会先于原来的过滤器执行,因为它的功能与老过滤器完全一样,所以这就等于把原来的过滤器替换掉了 -->
<http auto-config='true' access-denied-page="/accessDenied.jsp">
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
</http> <!-- users-by-username-query为根据用户名查找用户,系统通过传入的用户名查询当前用户的登录名,密码和是否被禁用这一状态。authorities-by-username-query为根据用户名查找权限,系统通过传入的用户名查询当前用户已被授予的所有权限 -->
<authentication-manager>
<authentication-provider>
<!-- 增加MD5加密 -->
<password-encoder hash="md5">
<!-- 盐值加密:在password-encoder下添加了salt-source,并且指定使用username作为盐值 -->
<salt-source user-property="username"/>
</password-encoder>
<jdbc-user-service data-source-ref="dataSource"
cache-ref="userCache"
users-by-username-query="select username,password,status as enabled
from user
where username=?"
authorities-by-username-query="select u.username,r.name as authority
from user u
join user_role ur
on u.id=ur.user_id
join role r
on r.id=ur.role_id
where u.username=?" />
</authentication-provider>
</authentication-manager> <!-- 缓存begin -->
<b:bean id="userCache"
class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
<b:property name="cache" ref="userEhCache" />
</b:bean> <b:bean id="userEhCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<b:property name="cacheManager" ref="cacheManager" />
<b:property name="cacheName" value="userCache" />
</b:bean> <b:bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
<!-- 缓存end --> <b:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
autowire="byType">
<b:property name="securityMetadataSource" ref="filterInvocationSecurityMetadataSource" />
<b:property name="authenticationManager"
ref="org.springframework.security.authenticationManager" />
</b:bean> <b:bean id="filterInvocationSecurityMetadataSource"
class="com.github.humeng126.security_01.JdbcFilterInvocationDefinitionSourceFactoryBean">
<b:property name="dataSource" ref="dataSource" />
<b:property name="resourceQuery"
value="
select re.res_string,r.name
from role r
join resc_role rr
on r.id=rr.role_id
join resc re
on re.id=rr.resc_id
order by re.priority
" />
</b:bean> <b:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<b:property name="locations">
<b:list>
<b:value>classpath*:application.properties</b:value>
</b:list>
</b:property>
</b:bean>
<!-- 数据源配置, 使用DBCP数据库连接池 -->
<b:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<!-- Connection Info -->
<b:property name="driverClassName" value="${jdbc.driver}" />
<b:property name="url" value="${jdbc.url}" />
<b:property name="username" value="${jdbc.username}" />
<b:property name="password" value="${jdbc.password}" /> <!-- Connection Pooling Info -->
<b:property name="maxActive" value="${dbcp.maxActive}" />
<b:property name="maxIdle" value="${dbcp.maxIdle}" />
<b:property name="defaultAutoCommit" value="false" />
<!-- 连接Idle一个小时后超时 -->
<b:property name="timeBetweenEvictionRunsMillis" value="3600000" />
<b:property name="minEvictableIdleTimeMillis" value="3600000" />
</b:bean>
</b:beans>
- 数据库表
表里面的基本信息,业务系统可以根据自己的需求灵活定制
-- 资源
create table resc(
id bigint,
name varchar(50),
res_type varchar(50),
res_string varchar(200),
priority integer,
descn varchar(200)
);
alter table resc add constraint pk_resc primary key(id);
alter table resc alter column id bigint generated by default as identity(start with 1); -- 角色
create table role(
id bigint,
name varchar(50),
descn varchar(200)
);
alter table role add constraint pk_role primary key(id);
alter table role alter column id bigint generated by default as identity(start with 1); -- 用户
create table user(
id bigint,
username varchar(50),
password varchar(50),
status integer,
descn varchar(200)
);
alter table user add constraint pk_user primary key(id);
alter table user alter column id bigint generated by default as identity(start with 1); -- 资源角色连接表
create table resc_role(
resc_id bigint,
role_id bigint
);
alter table resc_role add constraint pk_resc_role primary key(resc_id, role_id);
alter table resc_role add constraint fk_resc_role_resc foreign key(resc_id) references resc(id);
alter table resc_role add constraint fk_resc_role_role foreign key(role_id) references role(id); -- 用户角色连接表
create table user_role(
user_id bigint,
role_id bigint
);
alter table user_role add constraint pk_user_role primary key(user_id, role_id);
alter table user_role add constraint fk_user_role_user foreign key(user_id) references user(id);
alter table user_role add constraint fk_user_role_role foreign key(role_id) references role(id);
insert into user(id,username,password,status,descn) values(1,'admin','admin',1,'管理员');
insert into user(id,username,password,status,descn) values(2,'user','user',1,'用户'); insert into role(id,name,descn) values(1,'ROLE_ADMIN','管理员角色');
insert into role(id,name,descn) values(2,'ROLE_USER','用户角色'); insert into resc(id,name,res_type,res_string,priority,descn) values(1,'','URL','/admin.jsp',1,'');
insert into resc(id,name,res_type,res_string,priority,descn) values(2,'','URL','/**',2,''); insert into resc_role(resc_id,role_id) values(1,1);
insert into resc_role(resc_id,role_id) values(2,1);
insert into resc_role(resc_id,role_id) values(2,2); insert into user_role(user_id,role_id) values(1,1);
insert into user_role(user_id,role_id) values(1,2);
insert into user_role(user_id,role_id) values(2,2);
- 权限过滤
package com.github.humeng126.security_01; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import javax.sql.DataSource; import org.springframework.beans.factory.FactoryBean;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.ConfigAttributeEditor;
import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; public class JdbcFilterInvocationDefinitionSourceFactoryBean extends
JdbcDaoSupport implements FactoryBean { private String resourceQuery; public Object getObject() throws Exception {
return new DefaultFilterInvocationSecurityMetadataSource(
this.buildRequestMap());
} public Class getObjectType() {
return FilterInvocationSecurityMetadataSource.class;
} public boolean isSingleton() {
return true;
} protected Map<String, String> findResources() {
ResourceMapping resourceMapping = new ResourceMapping(getDataSource(),
resourceQuery);
Map<String, String> resourceMap = new LinkedHashMap<String, String>();
// 执行它的execute()方法获得所有资源信息
for (Resource resource : (List<Resource>) resourceMapping.execute()) {
String url = resource.getUrl();
String role = resource.getRole();
if (resourceMap.containsKey(url)) {
String value = resourceMap.get(url);
resourceMap.put(url, value + "," + role);
} else {
resourceMap.put(url, role);
}
}
return resourceMap;
} protected LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> buildRequestMap() {
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = null;
requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
ConfigAttributeEditor editor = new ConfigAttributeEditor();
Map<String, String> resourceMap = this.findResources();
// 使用urlMatcher和requestMap创建DefaultFilterInvocationDefinitionSource
for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
String key = entry.getKey();
editor.setAsText(entry.getValue());
requestMap.put(new AntPathRequestMatcher(key),
(Collection<ConfigAttribute>) editor.getValue());
}
return requestMap;
} // 通过定义一个MappingSqlQuery实现数据库操作
private class ResourceMapping extends MappingSqlQuery {
protected ResourceMapping(DataSource dataSource, String resourceQuery) {
super(dataSource, resourceQuery);
compile();
} protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String url = rs.getString(1);
String role = rs.getString(2);
Resource resource = new Resource(url, role);
return resource;
}
} private class Resource {
private String url;
private String role; public Resource(String url, String role) {
this.url = url;
this.role = role;
} public String getUrl() {
return url;
} public String getRole() {
return role;
}
} public String getResourceQuery() {
return resourceQuery;
} public void setResourceQuery(String resourceQuery) {
this.resourceQuery = resourceQuery;
} }
- 修改权限,动态刷新页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="org.springframework.context.ApplicationContext"%>
<%@page
import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.beans.factory.FactoryBean"%>
<%@page
import="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"%>
<%@page
import="org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource"%>
<%
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(application);
FactoryBean factoryBean = (FactoryBean) ctx
.getBean("&filterInvocationSecurityMetadataSource");
FilterInvocationSecurityMetadataSource fids = (FilterInvocationSecurityMetadataSource) factoryBean
.getObject();
FilterSecurityInterceptor filter = (FilterSecurityInterceptor) ctx
.getBean("filterSecurityInterceptor");
filter.setSecurityMetadataSource(fids);
%>
<jsp:forward page="/" />
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body> </body>
</html>
Spring security3的更多相关文章
- Spring Security3学习实例
Spring Security是什么? Spring Security,这是一种基于Spring AOP和Servlet过滤器的安全框架.它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理 ...
- Spring Security3实现,权限动态获取
Spring Security3实现,权限动态获取 原文 http://blog.csdn.net/yangwei19680827/article/details/9359113 主题 网络安全Sp ...
- Spring Security3详细配置
Spring Security3详细配置 表名:RESOURCE 解释:资源表备注: 资源表 RESOURCE(资源表) 是否主键 字段名 字段描述 数据类型 长度 可空 约束 缺省值 备注 是 ID ...
- Spring Security3 - MVC 整合教程
下面我们将实现关于Spring Security3的一系列教程. 最终的目标是整合Spring Security + Spring3MVC 完成类似于SpringSide3中mini-web的功能 ...
- JavaEE学习之Spring Security3.x——模拟数据库实现用户,权限,资源的管理
一.引言 因项目需要最近研究了下Spring Security3.x,并模拟数据库实现用户,权限,资源的管理. 二.准备 1.了解一些Spring MVC相关知识: 2.了解一些AOP相关知识: 3. ...
- Spring Security3十五日研究(转载)
前言 南朝<述异记>中记载,晋王质上山砍柴,见二童子下棋,未看完,斧柄已烂,下山回村,闻同代人都去世了,自已还未变老. 因此发出“山中方一日,世上几千年” 的慨叹.原文寥寥几笔,读来 ...
- spring security3.1配置比较纠结的2个问题
转自:http://www.iteye.com/topic/1122629 总论无疑问的,spring security在怎么保护网页应用安全上做得很强很周全,但有些地方还是很差强人意,比如对< ...
- 使用Spring Security3的四种方法概述
使用Spring Security3的四种方法概述 那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中,已经实现过, ...
- Spring Security3中的-authentication-manager标签详解
讲解完http标签的解析过程,authentication-manager标签解析部分就很容易理解了 authentication-manager标签在spring的配置文件中的定义一般如下 < ...
随机推荐
- oracle 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值
create or replace function MAX_O3_8HOUR_ND(value NUMBER) return NUMBER parallel_enable aggregate usi ...
- Java 门面模式 浅析
Java中的门面模式,一般来说他的用途是隐藏一些不希望用户看到的东西,比如方法,变量,并且这些变量是不能够设置成私有的,因为在系统内部有些地方需要调用.在Tomcat的HttpServletReque ...
- PHP编写的图片验证码类文件分享方法
适用于自定义的验证码类! <?php/* * To change this license header, choose License Headers in Project Propertie ...
- Mysql数据库知识-Mysql索引总结 mysql mysql数据库 mysql函数
mysql数据库知识-Mysql索引总结: 索引(Index)是帮助MySQL高效获取数据的数据结构. 下边是自己整理的资料与自己的学习总结,,做一个汇总. 一.真的有必要使用索引吗? 不是每一个性能 ...
- 深入理解GCD(一)
虽然 GCD 已经出现过一段时间了,但不是每个人都明了其主要内容.这是可以理解的:并发一直很棘手,而 GCD 是基于 C 的 API ,它们就像一组尖锐的棱角戳进 Objective-C 的平滑世界. ...
- 线程属性pthread_attr_t
转:http://blog.sina.com.cn/s/blog_6dc9e4cf0100xcvk.html1. 线程属性: 使用pthread_attr_t类型表示,我 ...
- Dive into python学习笔记
http://woodpecker.org.cn/diveintopython/index.html 1.第一个程序odbchelper.py def buildConnectionString(pa ...
- python-学习笔记之-Day5 双层装饰器 字符串格式化 python模块 递归 生成器 迭代器 序列化
1.双层装饰器 #!/usr/bin/env python # -*- coding: utf-8 -*- # author:zml LOGIN_INFO = False IS_ADMIN = Fal ...
- Poj(1325),最小点覆盖
题目链接:http://poj.org/problem?id=1325 Machine Schedule Time Limit: 1000MS Memory Limit: 10000K Total ...
- Codeforces Round #373 (Div. 2) B
Description Anatoly lives in the university dorm as many other students do. As you know, cockroaches ...