spring secutity3

聽說springsecurity功能很強大,昨天小運行了個例子,貼出來與大家分享。

聯繫方式QQ:263090670

關於配置:

1 )在 web.xml 中添加紅色部分,引入spring安全框架

<?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">

 <display-name>ab</display-name>
 <!-- Spring ApplicationContext配置文件的路徑,可使用通配符,多個路徑用,號分隔
  此參數用於後面的Spring Context Loader -->
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   classpath*:/applicationContext.xml
   classpath*:/applicationContext-security.xml
  </param-value>
 </context-param>

 <!-- Filter 定義  -->
 <!-- Character Encoding filter -->
 <filter>
  <filter-name>encodingFilter</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>

 <!-- Hibernate Open Session In View filter-->
 <filter>
  <filter-name>hibernateOpenSessionInViewFilter</filter-name>
  <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
 </filter>

 <!-- SpringSecurity filter-->
 <filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>

 <!-- Struts2 filter -->
 <filter>
  <filter-name>struts2CleanupFilter</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
 </filter>
 <filter>
  <filter-name>struts2Filter</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 </filter>

 <!-- Filter 映射 -->
 <filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>hibernateOpenSessionInViewFilter</filter-name>
  <url-pattern>*.action</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
 </filter-mapping>
 <filter-mapping>
  <filter-name>hibernateOpenSessionInViewFilter</filter-name>
  <url-pattern>/j_spring_security_check</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
 </filter-mapping>

 <filter-mapping>
  <filter-name>struts2CleanupFilter</filter-name>
  <url-pattern>*.action</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
 </filter-mapping>

 <filter-mapping>
  <filter-name>struts2Filter</filter-name>
  <url-pattern>*.action</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
 </filter-mapping>

 <!--Spring的ApplicationContext 載入 -->
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

 <!-- Spring 刷新Introspector防止內存泄露 -->
 <listener>
  <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
 </listener>

 <!-- session超時定義,單位爲分鐘 -->
 <session-config>
  <session-timeout>20</session-timeout>
 </session-config>

 <!-- 出錯頁面定義 -->
 <error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/common/500.jsp</location>
 </error-page>
 <error-page>
  <error-code>500</error-code>
  <location>/common/500.jsp</location>
 </error-page>
 <error-page>
  <error-code>404</error-code>
  <location>/common/404.jsp</location>
 </error-page>
 <error-page>
  <error-code>403</error-code>
  <location>/common/403.jsp</location>
 </error-page>
</web-app>

2)applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="http://www.springframework.org/schema/security"
 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.0.xsd"
 default-lazy-init="true">

 <description>SpringSecurity安全配置</description>
 <bean id="myFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"></property>
  <property name="accessDecisionManager">
   <bean class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="decisionVoters">
    <list>
     <bean class="org.springframework.security.access.vote.RoleVoter"></bean>
    </list>
    </property>
   
   </bean>
  </property>
  <property name="securityMetadataSource" ref="resourceService"></property>
 </bean>

 <!-- http安全配置 -->
 <s:http auto-config="true" use-expressions="true">
  <s:intercept-url pattern="/css/**" filters="none" />
  <s:intercept-url pattern="/img/**" filters="none" />
  <s:intercept-url pattern="/js/**" filters="none" />
  <!--
  <s:intercept-url pattern="/account/user!save*" access="hasAnyRole('ROLE_修改用戶')" />
  <s:intercept-url pattern="/account/user!delete*" access="hasAnyRole('ROLE_修改用戶')" />
  <s:intercept-url pattern="/account/user*" access="hasAnyRole('ROLE_瀏覽用戶')" />
  <s:intercept-url pattern="/account/role!save*" access="hasAnyRole('ROLE_修改角色')" />
  <s:intercept-url pattern="/account/role!delete*" access="hasAnyRole('ROLE_修改角色')" />
  <s:intercept-url pattern="/account/role*" access="hasAnyRole('ROLE_瀏覽角色')" />
  -->  

<!-- 下面紅色部分說明 ref="myFilter"  自定義返回配置  等同於 <s:intercept-url pattern="/account/role*" access="hasAnyRole('ROLE_瀏覽角色')" />
-->
  <s:custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
  <s:form-login login-page="/login.action" default-target-url="/" authentication-failure-url="/login.action?error=true" />
  <s:logout logout-success-url="/" />
 </s:http>

 <!-- 認證配置, 使用userDetailsService提供的用戶信息 -->
 <s:authentication-manager alias="authenticationManager">
  <s:authentication-provider user-service-ref="userDetailsService">
   <s:password-encoder hash="plaintext" />
  </s:authentication-provider>
 </s:authentication-manager>

 <!-- 項目實現的用戶查詢服務 -->
 <bean id="userDetailsService" class="com.service.account.UserDetailsServiceImpl" />
</beans>

 

3)applicationContext.xml中添加配置

<bean id="resourceService" class="com.service.account.ResourceServiceImp"/>

 

關於自定義類:

1)UserDetailsServiceImpl.java

說明:loadUserByUsername 爲核心方法 返回自定義驗證信息。

package com.service.account;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import com.entity.account.Authority;
import com.entity.account.Role;
import com.entity.account.User;

import com.google.common.collect.Sets;

/**
 * 實現SpringSecurity的UserDetailsService接口,實現獲取用戶Detail信息的回調函數.
 *
 * @author calvin
 */
@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {

 private AccountManager accountManager;

 /**
  * 獲取用戶Details信息的回調函數.
  */
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {

  User user = accountManager.findUserByLoginName(username);
  if (user == null) {
   throw new UsernameNotFoundException("用戶" + username + " 不存在");
  }

  Set<GrantedAuthority> grantedAuths = obtainGrantedAuthorities(user);
  
  Set<GrantedAuthority> grantedAuths1=Sets.newHashSet();
  grantedAuths1.add(new GrantedAuthorityImpl("ROLE_瀏覽角色"));

  //-- jcs示例中無以下屬性, 暫時全部設爲true. --//
  boolean enabled = true;
  boolean accountNonExpired = true;
  boolean credentialsNonExpired = true;
  boolean accountNonLocked = true;

  UserDetails userdetails = new org.springframework.security.core.userdetails.User(user.getLoginName(), user
    .getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths);

  return userdetails;
 }

 /**
  * 獲得用戶所有角色的權限集合.
  */
 private Set<GrantedAuthority> obtainGrantedAuthorities(User user) {
  Set<GrantedAuthority> authSet = Sets.newHashSet();
  for (Role role : user.getRoleList()) {
   for (Authority authority : role.getAuthorityList()) {
    authSet.add(new GrantedAuthorityImpl(authority.getPrefixedName()));
   }
  }
  return authSet;
 }

 @Autowired
 public void setAccountManager(AccountManager accountManager) {
  this.accountManager = accountManager;
 }
}

2)ResourceServiceImp.java 自定義配置信息

package com.service.account;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

public class ResourceServiceImp implements ResourceService{
 @Override
 public boolean supports(Class<?> arg0) {
  // TODO Auto-generated method stub
  return true;
 }
 
 @Override
 public Collection<ConfigAttribute> getAllConfigAttributes() {
  Set<ConfigAttribute> AllConfigAttributes=new HashSet<ConfigAttribute>();
  AllConfigAttributes.add(new SecurityConfig("ROLE_修改用戶"));
  AllConfigAttributes.add(new SecurityConfig("ROLE_修改用戶"));
  AllConfigAttributes.add(new SecurityConfig("ROLE_瀏覽用戶"));
  AllConfigAttributes.add(new SecurityConfig("ROLE_修改角色"));
  AllConfigAttributes.add(new SecurityConfig("ROLE_修改角色"));
  AllConfigAttributes.add(new SecurityConfig("ROLE_瀏覽角色"));
  return AllConfigAttributes;
 }

 //核心代碼
 @Override
 public Collection<ConfigAttribute> getAttributes(Object object)
   throws IllegalArgumentException {
  
  Map<String,Collection<ConfigAttribute>> resourceMap=new HashMap<String,Collection<ConfigAttribute>>();
  Collection<ConfigAttribute> collection3=new ArrayList<ConfigAttribute>();
  collection3.add(new SecurityConfig("ROLE_瀏覽用戶"));
  Collection<ConfigAttribute> collection4=new ArrayList<ConfigAttribute>();
  collection4.add(new SecurityConfig("ROLE_瀏覽角色"));
  
  
  Collection<ConfigAttribute> collection1=new ArrayList<ConfigAttribute>();
  collection1.add(new SecurityConfig("ROLE_修改角色"));
  //collection1.add(new SecurityConfig("ROLE_瀏覽角色"));
  //collection1.add(new SecurityConfig("ROLE_查看角色"));
  
  Collection<ConfigAttribute> collection=new ArrayList<ConfigAttribute>();
  
  collection.add(new SecurityConfig("ROLE_修改用戶"));
  //collection.add(new SecurityConfig("ROLE_瀏覽用戶"));
  //collection.add(new SecurityConfig("ROLE_查看用戶"));
  resourceMap.put("/account/user!save*", collection);
  resourceMap.put("/account/user!delete*", collection);
  resourceMap.put("/account/user*", collection3);
  
  resourceMap.put("/account/role!save*", collection1);
  resourceMap.put("/account/role!delete*", collection1);
  resourceMap.put("/account/role*", collection4);
  
  
  FilterInvocation filterInvocation=(FilterInvocation)object;
  String url=filterInvocation.getRequestUrl();
  UrlMatcher urlMatcher=new AntUrlPathMatcher();
  Iterator it=resourceMap.keySet().iterator();
  System.out.println("url:"+url);
  while(it.hasNext()){
   String reqUrl=(String)it.next();
   
   if(urlMatcher.pathMatchesUrl(reqUrl, url)){
    Collection<ConfigAttribute> collectionReturn=resourceMap.get(reqUrl);
    return collectionReturn;
   };
   
  }
  
  return null;
 }

 

}

3)ResourceService.java 自定義配置信息

package com.service.account;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public interface ResourceService extends FilterInvocationSecurityMetadataSource {

}

 


  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章