spring Security 3.1的配置(二)
四.将用户角色及权限放入数据库(mysql 5)。
首先先配置数据源,可以是任何的库。Jar包就用下载的ss3.1里的包就可以。以下以mysql为例。
1.定义三个表:用u_user,权限表u_authority,用户权限表u_role。
CREATE DATABASE initlife
CHARACTER SET utf8
COLLATE 'utf8_general_ci';
CREATE TABLE `u_user` (
`us_name` VARCHAR(50) NOT NULL,
`us_password` VARCHAR(50) NOT NULL,
`us_enabled` TINYINT(1) NULL DEFAULT NULL,
PRIMARY KEY (`us_name`),
UNIQUE INDEX `u_name` (`us_name`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
CREATE TABLE `u_authority` (
`au_authority` VARCHAR(50) NOT NULL,
`au_name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`au_authority`),
UNIQUE INDEX `au_authority` (`au_authority`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
CREATE TABLE `u_role` (
`ro_usname` VARCHAR(50) NOT NULL,
`ro_auauthority` VARCHAR(50) NULL DEFAULT NULL,
INDEX `FK_u_role_u_user` (`ro_usname`),
INDEX `FK_u_role_u_authority` (`ro_auauthority`),
CONSTRAINT `FK_u_role_u_authority` FOREIGN KEY (`ro_auauthority`) REFERENCES `u_authority` (`au_authority`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_u_role_u_user` FOREIGN KEY (`ro_usname`) REFERENCES `u_user` (`us_name`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
2.添加数据
INSERT INTO `u_authority` (`au_authority`, `au_name`) VALUES
('ROLE_ADMIN', '管理员'),
('ROLE_GUESS', '访客'),
('ROLE_USER', '普通用户');
INSERT INTO `u_role` (`ro_usname`, `ro_auauthority`) VALUES
('user', 'ROLE_USER'),
('user', 'ROLE_GUESS'),
('admin', 'ROLE_ADMIN'),
('admin', 'ROLE_USER'),
('guest', 'ROLE_GUESS');
INSERT INTO `u_user` (`us_name`, `us_password`, `us_enabled`) VALUES
('admin', '21232f297a57a5a743894a0e4a801fc3', 1),
('guest', '084e0343a0486ff05530df6c705c8bb4', 0),
('user', 'ee11cbb19052e40b07aac0ca060c23ee', 1);
3.修改
applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- 开启测试模式 -->
<!-- 自动配置模式,拦截所有请求进行匹配,有ROLE_USER才可以通过 -->
<http auto-config="true">
<!-- 指定不拦截登录页,* 表示可以带参数。从3.10开始,不再支持filters="none"配置 -->
<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<!-- 指定登录页面及登录失败跳转页 -->
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<password-encoder hash="md5"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select u.us_name username ,u.us_password password ,u.us_enabled enabled from u_user u where u.us_name = ? and u.us_enabled = 1"
authorities-by-username-query="select r.ro_usname,r.ro_auauthority from u_role r where r.ro_usname = ?" />
</authentication-provider>
</authentication-manager>
<!-- 指定中文资源 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/>
</beans:bean>
</beans:beans>
4.我的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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">
<!-- 指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下寻找 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<!-- 对Spring容器进行实例化 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载spring Security 过滤器 -->
<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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
5.我的另外配置文件
applicationContext-common.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.gjt.mm.mysql.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/sst?useUnicode=true&characterEncoding=UTF-8"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="1"/>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize" value="1"/>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="300"/>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60"/>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5"/>
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.format_sql=false
</value>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
6.可以发布测试了。
五.开启页面ss EL表达式
1.修改plicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- 开启测试模式 -->
<!-- 自动配置模式,拦截所有请求进行匹配,有ROLE_USER才可以通过 -->
<http auto-config="true" use-expressions="true" access-denied-page="/403.jsp" >
<!-- 指定不拦截登录页,* 表示可以带参数。从3.10开始,不再支持filters="none"配置 -->
<intercept-url pattern="/login.jsp*" access="permitAll" />
<intercept-url pattern="/user.jsp" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin.jsp" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<!-- 指定登录页面及登录失败跳转页 -->
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<password-encoder hash="md5"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select u.us_name username ,u.us_password password ,u.us_enabled enabled from u_user u where u.us_name = ? and u.us_enabled = 1"
authorities-by-username-query="select r.ro_usname,r.ro_auauthority from u_role r where r.ro_usname = ?" />
</authentication-provider>
</authentication-manager>
<!-- 指定中文资源 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/>
</beans:bean>
</beans:beans>
注:use-expressions="true" 不能与access="ROLE_****"或access="IS_AUTHENTICATED_ANONYMOUSLY"等一起应用,而需要改成如上的格式。
2.index.jsp 红色部分为标签库及表达式
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><sec:authentication property="name" />的首页!</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
这是首页,欢迎<sec:authentication property="name" /> ! <br />
<p>
<sec:authorize access="hasRole('ROLE_ADMIN')">
You are a administrator! You can therefore see the <a href="./admin.jsp">管理员页</a>.<br/><br/>
</sec:authorize>
</p>
<p>
<sec:authorize access="hasRole('ROLE_USER')">
You are a user! You can therefore see the <a href="./user.jsp">用户页</a>.<br/><br/>
</sec:authorize>
</p>
<p><a href="./">Home</a></p>
<p><a href="./j_spring_security_logout">Logout</a></p>
<sec:authorize ifAllGranted="ROLE_USER" >
<a href="user.jsp">进入user.jsp页面</a><br>
</sec:authorize>
ifAllGranted:只有当前用户拥有所有指定的权限时,才能显示标签体的内容 (相当于“与” 的关系)<br><br>
<sec:authorize ifAnyGranted="ROLE_ADMIN" >
<a href="user.jsp">进入user.jsp页面</a><br>
</sec:authorize>
ifAnyGranted:当前用户拥有指定的权限中的一个的时候,就能显示标签内部内容(相当于“或”的关系)<br><br>
<sec:authorize ifNotGranted="ROLE_ADMIN" >
<a href="user.jsp">进入user.jsp页面</a><br>
</sec:authorize>
ifNotGranted:没有指定的权限的时候,显示标签体的内容 (相当于“非”的关系)<br><br><br>
</body>
</html>
3.可以发布测试了。当不同权限的用户登录时,就有不同的效果。
这是首页,欢迎admin !
You are a administrator! You can therefore see the 管理员页.
You are a user! You can therefore see the 用户页.
Home
Logout
进入user.jsp页面ifAllGranted:只有当前用户拥有所有指定的权限时,才能显示标签体的内容 (相当于“与” 的关系)进入user.jsp页面ifAnyGranted:当前用户拥有指定的权限中的一个的时候,就能显示标签内部内容(相当于“或”的关系)ifNotGranted:没有指定的权限的时候,显示标签体的内容 (相当于“非”的关系)
~~~~~~~~~~~~~~~~~~~~我是分隔线~~~~~~~~~~~~~~~~~~~~~~~~~
这是首页,欢迎user !
You are a user! You can therefore see the 用户页.
Home
Logout
进入user.jsp页面ifAllGranted:只有当前用户拥有所有指定的权限时,才能显示标签体的内容 (相当于“与” 的关系)ifAnyGranted:当前用户拥有指定的权限中的一个的时候,就能显示标签内部内容(相当于“或”的关系)进入user.jsp页面ifNotGranted:没有指定的权限的时候,显示标签体的内容 (相当于“非”的关系)
六.防同账号多人登陆
1.web.xml增加一个监听
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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">
<!-- 指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下寻找 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<!-- 对Spring容器进行实例化 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<!-- 这个监听器会在session 创建和销毁的时候通知Spring Security。 -->
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<!-- 加载spring Security 过滤器 -->
<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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2. applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- 开启测试模式 -->
<!-- 自动配置模式,拦截所有请求进行匹配,有ROLE_USER才可以通过 -->
<http auto-config="true" use-expressions="true" access-denied-page="/403.jsp" >
<!-- 指定不拦截登录页,* 表示可以带参数。从3.10开始,不再支持filters="none"配置 -->
<intercept-url pattern="/login.jsp*" access="permitAll" />
<intercept-url pattern="/timeout.jsp*" access="permitAll" />
<intercept-url pattern="/user.jsp" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin.jsp" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<!-- 指定登录页面及登录失败跳转页 -->
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
<!-- 指定成功退出系统后跳转页 -->
<logout logout-success-url="/login.jsp" />
<!-- 单用户登录,后登录者无法登录 -->
<session-management >
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
<!--session失效,超时页面。 -->
<session-management invalid-session-url="/timeout.htm" />
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<password-encoder hash="md5"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select u.us_name username ,u.us_password password ,u.us_enabled enabled from u_user u where u.us_name = ? and u.us_enabled = 1"
authorities-by-username-query="select r.ro_usname,r.ro_auauthority from u_role r where r.ro_usname = ?" />
</authentication-provider>
</authentication-manager>
<!-- 指定中文资源 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/>
</beans:bean>
</beans:beans>
3.发布,测成。。。。。