Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个资源来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
不多说了,直接上代码,这里采用springmvc与springSecurity结合。
web.xml配置
web.xml中主要配置了springmvc与springSecurity,指定了配置文件applicationContext*.xml与applicationContext-servlet.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" xmlns:web="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">
<!--ContextLoaderListener监听器,会创建WebApplicationContext实现类 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<!-- springmvc配置 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-servlet.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>
<!-- 强制进行转码为utf8 -->
<filter>
<filter-name>Set Character Encoding</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>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 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>
</web-app>
springmvc的配置 applicationContext-servlet.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- 自动扫描Controller类 -->
<context:component-scan base-package="com.xj.action"/>
<!-- 定义视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<mvc:resources mapping="/asserts/**" location="/asserts/"/>
</beans>
数据库连接配置 applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="propertyConfigurer" class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<property name="location" value= "/WEB-INF/config.properties" />
</bean>
<bean id="language" class="com.xj.util.Language" >
<property name="location" value= "/WEB-INF/lang.properties" />
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="maxIdleTime" value="${jdbc.maxIdleTime}" />
<property name="acquireIncrement" value="${jdbc.acquireIncrement}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="initialPoolSize" value="${jdbc.initialPoolSize}" />
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}" />
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}" />
<property name="breakAfterAcquireFailure" value="${jdbc.breakAfterAcquireFailure}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnectionOnCheckout}" />
</bean>
<!-- 注册一个JDBC数据源事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- -->
<!-- 基于@Transactional注解方式的事务管理 -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- 这里路径需要修改 -->
<!-- 配置自动扫描组件 -->
<context:component-scan base-package="com.xj.dao" />
<context:component-scan base-package="com.xj.security" />
<context:component-scan base-package="com.xj.service" />
</beans>
上述配置中,需要用到config.properties相关连接信息
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/myhome?useUnicode=true&characterEncoding=utf-8
jdbc.user=root
jdbc.password=123
jdbc.minPoolSize=10
jdbc.maxPoolSize=20
jdbc.maxIdleTime=60
jdbc.acquireIncrement=2
jdbc.maxStatements=0
jdbc.initialPoolSize=2
jdbc.idleConnectionTestPeriod=60
jdbc.acquireRetryAttempts=30
jdbc.breakAfterAcquireFailure=false
jdbc.testConnectionOnCheckout=false
下面就开始重中之重了springSecurity的配置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.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/login" security="none" />
<http use-expressions="true" access-denied-page="/login" >
<form-login login-page="/login" authentication-failure-url="/login" default-target-url="/main" />
<logout logout-success-url="/login" />
<session-management invalid-session-url="/login">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
</session-management>
<custom-filter ref="myfilter" before="FILTER_SECURITY_INTERCEPTOR" />
<remember-me />
<logout invalidate-session="true" logout-success-url="/login" logout-url="/j_spring_security_logout"/>
</http>
<!--一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性 -->
<beans:bean id="myfilter" class="com.xj.security.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/> <!-- 认证管理器 -->
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" /> <!-- 决策管理器 -->
<beans:property name="securityMetadataSource" ref="securityMetadataSource"/> <!-- 安全元数据资源 -->
</beans:bean>
<authentication-manager alias="authenticationManager" >
<authentication-provider ref="authenticationProvider"> </authentication-provider>
</authentication-manager>
<beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="myUserDetailService" />
</beans:bean>
<beans:bean id="myUserDetailService" class="com.xj.security.MyUserDetailService" />
<!-- 决策管理器 -->
<beans:bean id="myAccessDecisionManager" class="com.xj.security.MyAccessDecisionManager"> </beans:bean>
<!-- 资源管理器 -->
<beans:bean id="securityMetadataSource" class="com.xj.security.MySecurityMetadataSource" ></beans:bean>
</beans:beans>
自定义filter拦截器FilterSecurityInterceptor,该方法需要继承AbstractSecurityInterceptor,其中最主要的是doFilter方法。
package com.xj.security;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
//自定义过滤器
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter{
//安全元数据资源
private MySecurityMetadataSource securityMetadataSource;
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
//可以这里进行相关操作
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
FilterInvocation fileInvocation = new FilterInvocation(request, response, chain);
InterceptorStatusToken interceptorStatusToken = this.beforeInvocation(fileInvocation); //校验访问的路径需要的角色等
fileInvocation.getChain().doFilter(request, response);
this.afterInvocation(interceptorStatusToken, null);
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
public MySecurityMetadataSource getSecurityMetadataSource() {
return securityMetadataSource;
}
public void setSecurityMetadataSource(
MySecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
this.securityMetadataSource.refreshResource();
}
}
由FilterSecurityInterceptor的配置可以看出,其需要认证管理器authenticationManager,决策管理器accessDecisionManager,资源管理器securityMetadataSource
认证管理器authenticationManager中,最主要的是UserDetailsService,该方法将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用
package com.xj.security;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.xj.dao.CommonDao;
//身份认证管理器
public class MyUserDetailService implements UserDetailsService{
@Autowired
private CommonDao commonDao;
@Override
public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
GrantedAuthority ga = null;
String sql="select * from auth_user where username=?";
Map userMap = commonDao.queryForOne(sql, username);
if(userMap==null||userMap.size()==0){
throw new UsernameNotFoundException("用户" + username + " 不存在");
}
if(userMap.get("enabled").toString().equals("false")){
throw new DisabledException("用户" + username + " 被冻结");
}
String password = userMap.get("password").toString();
String roleIds[] = ( (String)userMap.get("roleId")).split(",");
sql = "select * from auth_role where id=?";
for(String roleId:roleIds){
Map roleMap = commonDao.queryForOne(sql, roleId);
String rolename = (String)roleMap.get("rolename");
ga = new GrantedAuthorityImpl(rolename);
grantedAuthorities.add(ga);
}
User user = new User(username, password, true, true, true, true, grantedAuthorities);
return user;
}
}
资源管理器,需要继承FilterInvocationSecurityMetadataSource服务器启动时,即加载数据库的资源信息
package com.xj.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import com.xj.dao.CommonDao;
//资源管理器(统计出要访问的资源需要的角色)
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource{
@Autowired
private CommonDao commonDao;
private Map<String, Collection<ConfigAttribute>> resourceMap=null;
//从数据库加载资源
public Map loadSource(){
resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
String resource_sql="select * from auth_resource";
String role_sql="select * from auth_role";
List<Map> resources = commonDao.queryForList(resource_sql);
List<Map> roles = commonDao.queryForList(role_sql);
Map<String,String> roleMap = new HashMap<String,String>(); //对应了role表的map
for(Map role:roles){
String id = role.get("id").toString();
String rolename = (String)role.get("rolename");
roleMap.put(id, rolename);
}
for(Map resource:resources){
Collection<ConfigAttribute> collection=new ArrayList<ConfigAttribute>();
String url_pattern = (String)resource.get("url_pattern");
String access_role = (String)resource.get("access_role");
String roleIds[] = access_role.split(",");
for(String roleId:roleIds){
ConfigAttribute ca = new SecurityConfig(roleMap.get(roleId));
collection.add(ca);
}
resourceMap.put(url_pattern, collection);
}
return resourceMap;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
//获取访问某一个url所需的角色
@Override
public Collection<ConfigAttribute> getAttributes(Object arg0)
throws IllegalArgumentException {
String url =((FilterInvocation)arg0).getRequestUrl();
if(resourceMap==null){
System.out.println("无访问权限");
return null;
}
Collection<ConfigAttribute> collection = resourceMap.get(url);
return collection;
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
/**
* 刷新资源配置
*/
public void refreshResource(){
loadSource();
}
}
需要commonDao类,可以算是一个公共类了
package com.xj.dao;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Repository;
import com.xj.util.Logger;
import com.xj.util.PageInfo;
@Repository("commonDao")
public class CommonDao {
@Autowired
DataSource dataSource;
public int execUp(String sql, final String params[])
throws SQLException {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate.update(sql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setString(i + 1, params[i]);
}
}
}
});
}
public List<Properties> execSql(String sql, final String params[]) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate.query(sql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setString(i + 1, params[i]);
}
}
}
}, new ItemMapper());
}
protected class ItemMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Properties item = new Properties();
ResultSetMetaData rsmd = rs.getMetaData();
int len = rsmd.getColumnCount();
for (int i = 0; i < len; i = i + 1) {
String colname = rsmd.getColumnName(i + 1);
try {
item.setProperty(colname, rs.getString(colname));
} catch (NullPointerException ex) {
}
}
return item;
}
}
public List queryForList(String sql, Object...objects) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
System.out.println(sql);
List list = jdbcTemplate.queryForList(sql,objects);
return list;
}
public int queryForInt(String sql,Object...objects) {
System.out.println(sql);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
int result = jdbcTemplate.queryForInt(sql,objects);
return result;
}
public int execute(String sql,Object...objects) {
sql += ";";
String[] tempArray = sql.split("\\?");
String tempSql = tempArray[0];
for(int i=0;i<objects.length;i++){
tempSql += "'"+objects[i]+"'"+tempArray[i+1];
}
System.out.println(tempSql);
if( SecurityContextHolder.getContext().getAuthentication()!=null){
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Logger.logByDate("/data/log/sql/", "operation_sql", userDetails.getUsername()+"\t"+tempSql);
}
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate.update(sql,objects);
}
/**
* 分页查询
* @param sql
* @param currentPage
* @param numPerPage
* @param objects
* @return
*/
public PageInfo queryForPage(String sql, int currentPage, int numPerPage,Object...objects) {
PageInfo pageinfo = new PageInfo();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// String countsql = sql.replace(new String("*"), new String("COUNT(*)"));
String countsql = "select COUNT(*) from (" + sql + ") as z";
if(sql.startsWith("SELECT *")){
if(sql.indexOf("WHERE")==-1 && sql.indexOf("where")==-1){
countsql = sql.replaceFirst("SELECT \\*", "SELECT COUNT(\\*)");
}
}
System.out.println(countsql);
int count = jdbcTemplate.queryForInt(countsql,objects);
pageinfo.setTotalCount(count);
sql = sql + " Limit " + (currentPage - 1) * numPerPage + "," + numPerPage;
//System.out.println(sql);
List list = jdbcTemplate.queryForList(sql,objects);
pageinfo.setCurrentPage(currentPage);
pageinfo.setNumPerPage(numPerPage);
pageinfo.setResult(list);
return pageinfo;
}
/**
* 查询单条记录
* @param sql
* @param objects
* @return
*/
public Map queryForOne(String sql,Object...objects) {
Map map = new HashMap();
sql +=" limit 1";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
System.out.println(sql);
List<Map<String,Object>> list = jdbcTemplate.queryForList(sql,objects);
if(list.size()!=0){
return list.get(0);
}else{
return map;
}
}
/**
* 插入Map 数据,key对应字段名,value对应字段值
* @param map
* @param tableName
* @param replace
* @return
*/
public int insertMap(Map<String,String> map,String tableName,boolean replace){
int r = -1;
int size = map.size();
String params[] = new String[size];
int index = 0;
String insertkeySql = "";
String insertValueSql = "";
String comma = "";
Iterator<Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = (Entry<String, String>) it.next();
String k = entry.getKey();
String v = entry.getValue();
insertkeySql += comma + "`" + k + "`";
insertValueSql += comma + " ? ";
comma = ", ";
params[index] = v;
index++;
}
String method = replace ? "REPLACE" : "INSERT";
String sql = method + " INTO " + tableName + " (" + insertkeySql
+ " ) VALUES ( " + insertValueSql + " )";
try {
r = this.execUp(sql, params);
} catch (Exception e) {
e.printStackTrace();
}
return r;
}
/**
* 更新数据表
* @param setal 更新数据Map
* @param whereal 条件Map
* @param tablename 表名
* @return
*/
public int updateTable(Map<String, String> setal,
Map<String, String> whereal, String tablename) {
int r = -1;
int size = setal.size() + whereal.size();
String params[] = new String[size];
int kid = 0;
String setsql = "";
String comma = "";
Iterator<Entry<String, String>> it = setal.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = (Entry<String, String>) it.next();
String k = entry.getKey();
String v = entry.getValue();
setsql += comma + "`" + k + "`" + " = ? ";
comma = ", ";
params[kid] = v;
kid++;
}
String where = "";
comma = "";
it = whereal.entrySet().iterator();
while (it.hasNext()) {
if (where.equals("")) {
where = " WHERE ";
}
Entry<String, String> entry = (Entry<String, String>) it.next();
String k = entry.getKey();
String v = entry.getValue();
String[] kw = k.split("[\\s,]");
if (kw.length == 2) {
where += comma + " `" + kw[0] + "`" + " " + kw[1] + " ? ";
} else if (kw.length == 3) {
where += kw[0] + " `" + kw[1] + "`" + " " + kw[2] + " ? ";
} else {
where += comma + " `" + kw[0] + "`" + " = ? ";
}
comma = " AND ";
params[kid] = v;
kid++;
}
String sql = "UPDATE " + tablename + " SET " + setsql + where;
// System.out.println( sql );
try {
r = this.execUp(sql, params);
} catch (Exception e) {
e.printStackTrace();
}
return r;
}
/**
* 查询表
* @param columnNameSet
* @param whereMap
* @param orderBy
* @param page
* @param pageCount
* @param tableName
* @param onlyOne
* @return
*/
public List<Properties> selectTable(Set<String> columnNameSet,
Map<String, String> whereMap, String orderBy, int page,
int pageCount, String tableName, boolean onlyOne) {
int size = 0;
String params[] = null;
if (whereMap != null && whereMap.size() > 0) {
size = whereMap.size();
params = new String[size];
}
int kid = 0;
String keysql = "";
String comma = "";
if (columnNameSet != null && columnNameSet.size() != 0) {
for (String s : columnNameSet) {
if (s.indexOf("(") != -1) {
keysql += comma + "" + s + "";
} else {
keysql += comma + "`" + s + "`";
}
comma = " , ";
}
} else {
keysql = " * ";
}
String where = "";
comma = "";
if (whereMap != null && whereMap.size() > 0) {
Iterator<Entry<String, String>> it = whereMap.entrySet().iterator();
while (it.hasNext()) {
if (where.equals("")) {
where = " WHERE ";
}
Entry<String, String> entry = (Entry<String, String>) it.next();
String k = entry.getKey();
String v = entry.getValue();
String[] kw = k.split("[\\s,]");
if (kw.length == 2) {
where += comma + " `" + kw[0] + "`" + " " + kw[1] + " ? ";
} else if (kw.length == 3) {
where += kw[0] + " `" + kw[1] + "`" + " " + kw[2] + " ? ";
} else {
where += comma + " `" + kw[0] + "`" + " = ? ";
}
comma = " AND ";
params[kid] = v;
kid++;
}
}
String order = "";
if (orderBy.equals("") == false) {
order = " ORDER BY " + orderBy;
}
String limit = "";
if (page > 0) {
if (pageCount <= 0) {
pageCount = 20;
}
int pageOffet = (page - 1) * pageCount;
limit = " LIMIT " + pageOffet + "," + pageCount;
}
if (onlyOne == true) {
limit = " LIMIT 1 ";
}
String sql = "SELECT " + keysql + " FROM " + tableName + where + order
+ limit;
System.out.println(sql);
List<Properties> l = null;
try {
l = this.execSql(sql, params);
} catch (Exception e) {
e.printStackTrace();
}
return l;
}
public Properties getItem(Map<String, String> whereMap, String tableName) {
Properties pp = null;
try {
List<Properties> l = selectTable(null, whereMap, "", -1, 0, tableName,true);
if (l != null && l.size() > 0) {
pp = l.get(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return pp;
}
public Properties getItemById(String id, String tableName) {
String sql = "SELECT * FROM " + tableName+ " WHERE `id` = ? Limit 1";
List<Properties> l = null;
Properties pp = null;
try {
l = this.execSql(sql, new String[] { id });
if (l != null && l.size() > 0) {
pp = l.get(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return pp;
}
public Map getItemById(long userId, String tableName) {
// TODO Auto-generated method stub
String sql = "SELECT * FROM " + tableName+ " WHERE `id` = ? Limit 1";
List<Properties> l = null;
Properties pp = null;
try {
l = this.execSql(sql, new String[] { String.valueOf(userId) });
if (l != null && l.size() > 0) {
pp = l.get(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return pp;
}
}
决策管理器AccessDecisionManager,判断用户的角色是否拥有操作的权限
package com.xj.security;
import java.util.Collection;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
//决策管理器
public class MyAccessDecisionManager implements AccessDecisionManager{
//auth用户具有的权限,attributes访问该资源所需的角色权限
@Override
public void decide(Authentication auth, Object object,Collection<ConfigAttribute> attributes) {
for(ConfigAttribute ca:attributes){ //访问资源需要的权限
String needRole = ((SecurityConfig)ca).getAttribute();
for(GrantedAuthority ga:auth.getAuthorities()){ //用户拥有的权限
String role = ga.getAuthority();
if(role.equals(needRole)){
return;
}
}
}
}
@Override
public boolean supports(ConfigAttribute arg0) {
return true;
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
基本配置就这样子
controller
package com.xj.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.xj.dao.CommonDao;
@Controller
public class HelloController {
@Autowired
private CommonDao commonDao;
@RequestMapping(value="/hello/justtest")
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
return new ModelAndView("/test");
}
@RequestMapping(value="/login")
public ModelAndView login(HttpServletRequest request,HttpServletResponse response) throws Exception {
return new ModelAndView("/login");
}
@RequestMapping(value="/main")
public ModelAndView loginSuccess(HttpServletRequest request,HttpServletResponse response) throws Exception {
return new ModelAndView("/main");
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<font color="red">
<c:choose>
<c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'Bad credentials'}">用户名或密码错误 </c:when>
<c:otherwise>
<c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"></c:out>
</c:otherwise>
</c:choose>
</font>
<br/>
<form action="j_spring_security_check" method="post">
用户名:<input type="text" name="j_username" /><br/>
密码:<input type="password" name="j_password"/> <br/>
<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox" value="true"/>记住我<br/>
<input type="submit" value="登陆"/>
</form>
</body>
</html>
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
this is main page
<a href="hello/justtest">继续前进</a>
<a href="j_spring_security_logout">退出</a>
</body>
</html>
大概就这样子了。
整个项目网盘地址为:http://yun.baidu.com/share/link?shareid=2188454084&uk=2836507213
转载于:https://blog.51cto.com/5148737/1615882