Spring Security 认证 根据数据库自动授权

 

<?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-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> <!-- org.springframework.security.providers.dao.cache.EhCacheBasedUserCache --> <beans:bean id="userCache" class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache"> <beans:property name="cache" ref="userEhCache" /> </beans:bean> <beans:bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> <beans:bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <beans:property name="cacheManager" ref="cacheManager" /> <beans:property name="cacheName" value="userCache" /> </beans:bean> <!-- jsp 资源保护 --> <http auto-config="true" access-denied-page="/common/403.jsp" session-fixation-protection="none"> <!-- intercept-url pattern="/admin.jsp" requires-channel="https"/ --> <!-- <intercept-url pattern="/" filters="none" />限制匿名登陆 --> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/" /> <logout logout-success-url="/login.jsp" /> <port-mappings> <port-mapping http="8080" https="9443" /> </port-mappings> <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" /> <!-- 匿名身份:Guest --> <anonymous username="Guest" /> </http> <!-- 用户 合法性认证 --> <authentication-provider> <password-encoder hash="md5" /> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="SELECT userinfo_name,userinfo_pwd,1 AS 'enabled' FROM up_userinfo WHERE userinfo_name = ? " authorities-by-username-query="SELECT up_userinfo.userinfo_name,('ROLE_'+LTRIM(str(up_role.role_id))) as 'role' FROM up_userrole inner join up_userinfo on up_userrole.userinfo_id=up_userinfo.userinfo_id inner join up_role on up_role.role_id=up_userrole.role_id WHERE up_userinfo.userinfo_name = ? " cache-ref="userCache" /> </authentication-provider> <beans:bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor" autowire="byType"> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" /> <beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" /> </beans:bean> <!-- 根据数据库中的内容自动为用户授权 --> <beans:bean id="filterInvocationDefinitionSource" class="org.springframework.security.SecureFilter.MySecureResourceFilter"> <beans:property name="dataSource" ref="dataSource" /> <beans:property name="resourceQuery" value="select distinct _source.resource_link, ('ROLE_'+LTRIM(str(_role.role_id))) as ROLE ,_role.role_name from up_role _role JOIN up_privilege _pri ON _role.role_id=_pri.role_id JOIN up_resource _source ON _pri.resource_id=_source.resource_id WHERE _source.resource_link not like ''" /> </beans:bean> <!-- 数据源 --> <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <beans:property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" /> <beans:property name="url" value="jdbc:jtds:sqlserver://localhost:1433;DatabaseName=eBuilder_egov;useLOBs=false" /> <beans:property name="username" value="sa" /> <beans:property name="password" value="sa1" /> </beans:bean> <!-- logger debug listener --> <beans:bean id="loggerListener" class="org.springframework.security.event.authentication.LogListener" /> </beans:beans>

 需要些什么包呢:

 

 

 此项目所需要的包

 

 

 

Web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 <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>
<listener>
    <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>

 

</web-app>

 

 

 

 

 

 

自定义的一个加载权限和角色对应的类

 

MySecureResourceFilter.java

 

 

package org.springframework.security.SecureFilter;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.RequestKey;
import org.springframework.security.util.AntUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;


/**
 * SS(Spring Security)  根据Web.xml指定的xml配置文件(在其中配置好resourceQuery)自动授权
 * @author 杨伦亮
 * Dec 14, 2010
 */
public class MySecureResourceFilter extends JdbcDaoSupport implements FactoryBean {
 private String resourceQuery;
 private final Log log=LogFactory.getLog(MySecureResourceFilter.class);
 public boolean isSingleton() {
  return true;
 }
 
 public Class getObjectType() {
  return FilterInvocationDefinitionSource.class;
 }
 /**
  * 我扩展的功能: urlMatcher和requestMap创建DefaultFilterInvocationDefinitionSource。
  */
 public Object getObject() {
  return new DefaultFilterInvocationDefinitionSource(this.getUrlMatcher(), this
        .buildRequestMap());
 }
 /**
  * 方法获得所有资源信息。<br>默认的情况是从XML配置文件中读取此信息即类似URL与ROLE_ADMIN信息。现在改为自定义地去查找数据库中的信息并与之对应
  * @return Map
  */
 protected Map<String, String> findResources() {
  //获得DataSource
  ResourceMapping resourceMapping = new ResourceMapping(getDataSource(), resourceQuery);
  
  Map<String, String> resourceMap = new LinkedHashMap<String, String>();
  String url,role,value;
  //execute()方法获得所有资源信息。
  Log log=LogFactory.getLog(MySecureResourceFilter.class);
  for(Resource resource : (List<Resource>) resourceMapping.execute()){
    url = resource.getUrl();
    role = resource.getRole();
   if(resourceMap.containsKey(url)){
     value = resourceMap.get(url);
     log.info(url+"\t授权:"+value+","+role+"\n");
    resourceMap.put(url, value +"," +role);
   }else{
    log.info(url+"\t授权:"+role+"\n");
    resourceMap.put(url, role);
   }
  }
  
  return resourceMap;
 }
 
 /**
  * 使用获得的资源信息组装requestMap。
  * @return LinkedHashMap
  */
 protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() {
  LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
  requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();
  
  ConfigAttributeEditor editor = new ConfigAttributeEditor();
  
  Map<String, String> resourceMap = this.findResources();
  
  for(Map.Entry<String, String> entry : resourceMap.entrySet()){
   RequestKey key = new RequestKey(entry.getKey(), null);
   editor.setAsText(entry.getValue());
   requestMap.put(key, (ConfigAttributeDefinition) editor.getValue());
  }
  
  return requestMap;
 }
 
 protected UrlMatcher getUrlMatcher() {
  return new AntUrlPathMatcher();
 }
 
 public void setResourceQuery(String resourceQuery) {
  log.info("setResourceQuery()\t"+resourceQuery);
  this.resourceQuery = resourceQuery;
 }
 
 /**
  * 资源属性<br>链接地址及角色名
  * @author 杨伦亮
  * Dec 15, 2010
  */
 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;
  }
 }
 
 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;
  }
 }
 
}

 

 

 

 

下面来测试一下配置信息是否对

admin.jsp

 

<%@ page language="java"
 import="java.util.*,org.springframework.security.*,org.springframework.security.userdetails.*,org.springframework.security.context.*"
 pageEncoding="UTF-8"%>
<%@ taglib prefix="sec"
 uri="http://www.springframework.org/security/tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <title>My JSP 'index.jsp' starting page</title>
  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  <meta http-equiv="description" content="This is my page">
 </head>
 <body >
 <h3>
  <a href="index.jsp">Home</a>&nbsp;&nbsp;|&nbsp;&nbsp;
  <a href="admin.jsp" target=_blank>试试访问受保护的jsp(403表示无权限访问)</a>&nbsp;&nbsp;|&nbsp;&nbsp;
  <a href="button_admin.jsp">只保护jsp中的按钮</a>&nbsp;&nbsp;|&nbsp;&nbsp;当前用户
  <a href="j_spring_security_logout">重新登陆</a>
  :
  <sec:authentication property="name"></sec:authentication>[${authentication.username }]
  
  <input type="button" value='<sec:authentication property="name" />' />
 </h3>
 
  <p>
   权限列表:
  </p>
  <%
   try{
    //当前登陆对象
    SecurityContext sec = SecurityContextHolder.getContext();
    UserDetails userDetails = (UserDetails) sec.getAuthentication().getPrincipal();
    out.print("["+userDetails.getUsername()+"]<br>");
    //取得权限列表
    GrantedAuthority[] authorities = userDetails.getAuthorities();
    
    for(int size = authorities.length, i = 0; i <size; i++){
     if(authorities[i] ==null)
      break;
     out.print("<br><font color=green>" +authorities[i] ==null ? "" : authorities[i].toString()+"</font>");
    }
   }catch(Exception e){
    out.print("<script>document.write('<font color=ffffff>Exception:!!!" +e.getMessage()
          +"</font>');</script>");
   }
  %>
  <font color=ffffff>
  <sec:authentication property="authorities" />
  </font>
  <br>
 <hr><h3>Session:</h3>
 <% 
 Enumeration<String> s=session.getAttributeNames();
 try{
 //UserDetails userdetails=(UserDetails)session.getAttribute();
   while(s.hasMoreElements()){
    String key=s.nextElement();
     out.println("<font color=red>"+key+"</font>&nbsp;<font color=green>"+session.getAttribute(key)+"</font><br>");
//这里的s.nextElement()就对应了每一个键名 通过他取值就可以了
   }
 }catch(java.util.NoSuchElementException e){
  out.println("认证失败"+e.getMessage());
 }
%>
 
 </body>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值