Spring security 3
最近ずっとspring security 3を勉強しています。環境を作ってみました。 maven環境を構築する
プロジェクト設定pom.xmlファイルで、web.xmlプロファイルにfilter を追加します。 springのaplication Contact.xml追加権限構成 データベーステーブル 表の基本情報は、業務システムが自分のニーズに応じて柔軟にカスタマイズできます。パーミッションフィルタ 権限を変更し、ページ を動的に更新する。
プロジェクト設定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>
<?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>
<?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>