(CRM开发)Spring-Security配置笔记

基本的配置步骤就是 web.xml ->applicationContext-security.xml->相关类的编写.

数据库大概: user->role->resource  两两之间都是多对多的关系 

1.web.xml配置:

<listener>
<listener-class>com.lowkey.crm.listener.ResourceLoaderListener </listener-class>
</listener>
 
<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>    
<filter>

配置一个监听器,使得我们项目启动的时候,我们就把所有的资源都放置在servletContext中,方便我们提取资源. 

关于DelegatingFilterProxy简而言之就是 提供web.xml和applicationContext之间的联系.地下的maaping 配置说明了过滤的范围.

2.我建立了一个新的xml文件 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.0.xsd">
...........好多配置在里面...............
</beans:beans>

——————————————...........好多配置在里面..............——————————————————————————

 <authentication-manager alias="authenticationManager">
<!-- 关于权限的业务逻辑,必须实现该接口 -->
<authentication-provider user-service-ref="securityService">
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>

注意securityService.这个类 我们是需要创建的.

拦截器配置:

<beans:bean  id ="resourceSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="objectD efinitionSource" ref="resourceFilterInvocationDefinitionSource"/>
<beans:property name="observeOncePerRequest"  value="false"></beans:property><!--很坑人,很严格的验证  -->
</beans:bean>

-----------resourceFilterInvocationDefinitionSource-------

<beans:bean id="resourceFilterInvocationDefinitionSource" 
class="com.lowkey.crm.security.ResourceFilterInvocationDefinitionSource">
</beans:bean>

------accessDecisionManager--------------

<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="allowIfAllAbstainDecisions" value="false"></beans:property>
<beans:property name="decisionVoters">
<beans:list>  <!-- 验证用户是否role开头 --> 
<beans:bean class="org.springframework.security.access.vote.RoleVoter"></beans:bean> 
<!-- 这里将用url获得的角色列表,与当前用户角色列表匹配 -->
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"></beans:bean>
</beans:list>
</beans:property>
</beans:bean>

--------403.jsp是我们需要跳转的错误页面并且login.jsp是不需要验证的--------

   <http access-denied-page="/403.jsp" auto-config="true" create-session="always">
<!-- 不用验证的路径 -->
<intercept-url pattern="/login.jsp" filters="none" />
<form-login login-page="/login.jsp" default-target-url="/index.action"
authentication-failure-url="/login.jsp?error=1" />
<logout logout-success-url="/login.jsp" />
<http-basic />
<remember-me key="testKey" services-ref="rememberMeServices"></remember-me>
<custom-filter after="FILTER_SECURITY_INTERCEPTOR" ref="resourceSecurityInterceptor"/>
</http>

----------关于rememberme的配置,就是说几天内登录都有效的那种东西------

<beans:bean id="resourceFilterInvocationDefinitionSource" 
class="com.lowkey.crm.security.ResourceFilterInvocationDefinitionSource">
</beans:bean>

<beans:bean id="remenberMeProcessingFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
<beans:property name="rememberMeServices" ref="rememberMeServices"></beans:property>
</beans:bean>

<beans:bean id ="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<beans:property name="userDetailsService" ref="securityService"></beans:property>
<beans:property name="key" value="testkey"/>
<beans:property name="tokenValiditySeconds" value="43200" /><!-- 5天 -->
</beans:bean>


3.相关类的编写:

监听器:

public class ResourceLoaderListener implements ServletContextListener{


//初始化执行的时候的操作
public void contextInitialized(ServletContextEvent servletContextEvent) {
// TODO Auto-generated method stub
//把数据库所有的Resource数据保存在application中.
 
ServletContext servleContext = servletContextEvent.getServletContext();
SecurityService securityService= 
(SecurityService) WebApplicationContextUtils.getWebApplicationContext(servleContext)
.getBean("securityService");
Map<String,String> urlRoles = securityService.getAllURLResouce();
servleContext.setAttribute("urlRoles", urlRoles);
System.out.println("~~~~~~~~~~~contextInitialized URLROLES:"+urlRoles.toString());
}

//销毁时执行的操作,服务停止时从application中移除所有资源
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// TODO Auto-generated method stub
servletContextEvent.getServletContext().removeAttribute("urlRoles");
}


}

  ---SecurityService的编写-----------------------------------------------


//注入:通过注解的方式获得一个bean
@Service("securityService")
public class SecurityServiceSupport extends HibernateDaoSupport  implements SecurityService,UserDetailsService{

@Autowired
public void init(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}

@SuppressWarnings("unchecked")
public Map<String, String> getAllURLResouce() {
// TODO Auto-generated method stub
//所有资源 都是url类型 
 
List<Resource> urlResource = this.getHibernateTemplate().find("FROM Resource");
Map<String,String> urls  = new HashMap<String, String>();
for(Iterator<Resource> it= urlResource.iterator();it.hasNext();){
Resource resource = it.next();
urls.put(resource.getValue(), resource.getRoleString());//通过url资源,找到所有能访问它的角色.
}
return urls;
}

public UserDetails loadUserByUsername(String name)
throws UsernameNotFoundException, DataAccessException {
System.out.println("~~~~~~~~~~~loadUserByUsername USERNAME:"+name);
List<User> users = null;
try {
users = this.getHibernateTemplate().find(
"FROM User user WHERE user.name=? AND user.disabled=false", name);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if(users.size()>0){
System.out.println("~~~~~~~~~~~~~~~~登陆的用户为:"+users.get(0).getName());
return (UserDetails) users.get(0);
}else{
System.out.println("用户:" + name + "没有找到!");
throw new UsernameNotFoundException("用户:" + name + "没有找到!");
}
// TODO Auto-generated method stub
}

}


 ----------------------ResourceFilterInvocationDefinitionSource的编写 -------------------------

public class ResourceFilterInvocationDefinitionSource 
implements FilterInvocationSecurityMetadataSource,InitializingBean{


//在spring 中 有两个类实现这个urlMatcher
//1.AntUrlPathMatcher 2.RegexUrlPathMatcher
private UrlMatcher urlMatcher;

private boolean useAntPath = true;
private boolean setpathlowercase = true;

public Collection getConfigAttributeDefinitions() {
// TODO Auto-generated method stub
return null;
}


public Collection<ConfigAttribute> getAttributes(Object filter)
throws IllegalArgumentException {
FilterInvocation filterInvocation = (FilterInvocation)filter;
ServletContext servletContext  = filterInvocation.getHttpRequest().getSession().getServletContext();
//取得了当前登录用户的所有角色
Map<String ,String > urlRoles = (Map<String, String>) servletContext.getAttribute("urlRoles");

//取得当前用户请求的路径.
String requestURL = filterInvocation.getRequestUrl();

//把用户请求的路径进行授权Role.因为资源表的所有数据都保存在了application里面了
String grantRoleStr = null;

for( Iterator<Map.Entry<String,String>> it = urlRoles.entrySet().iterator();it.hasNext();){
Map.Entry<String,String> entry =  it.next();
String url = entry.getKey();
System.out.println("url=============" + url);
if(urlMatcher.pathMatchesUrl(url, requestURL)){
grantRoleStr = entry.getValue();
break;
}
}
// TODO Auto-generated method stub
if(grantRoleStr!=null){
//这个类可以把以逗号分割的一系列字符串,转换为多个ConfigAttibute的ConfigAttributeDefinition对象
ConfigAttributeEditor configAttributeEditor = new ConfigAttributeEditor();
configAttributeEditor.setAsText(grantRoleStr);
return   (Collection<ConfigAttribute>) configAttributeEditor.getValue();
}
return null;
}




 


public void afterPropertiesSet() throws Exception {
  System.out.println("afterPropertiesSet()");


this.urlMatcher = new RegexUrlPathMatcher();


if (useAntPath) {
this.urlMatcher = new AntUrlPathMatcher();
}
System.out.println("this.urlMatcher" + this.urlMatcher);
if ("true".equals(setpathlowercase)) {
if (!this.useAntPath) {
((RegexUrlPathMatcher) this.urlMatcher)
.setRequiresLowerCaseUrl(true);
}
} else if ("false".equals(setpathlowercase)) {
if (this.useAntPath) {
((AntUrlPathMatcher) this.urlMatcher)
.setRequiresLowerCaseUrl(false);
}
}
System.out.println("this.urlMatcher" + this.urlMatcher);
}


public UrlMatcher getUrlMatcher() {
return urlMatcher;
}


public void setUrlMatcher(UrlMatcher urlMatcher) {
this.urlMatcher = urlMatcher;
}


public boolean isUseAntPath() {
return useAntPath;
}


public void setUseAntPath(boolean useAntPath) {
this.useAntPath = useAntPath;
}


public boolean isSetpathlowercase() {
return setpathlowercase;
}


public void setSetpathlowercase(boolean setpathlowercase) {
this.setpathlowercase = setpathlowercase;
}


public Collection<ConfigAttribute> getAllConfigAttributes() {
// TODO Auto-generated method stub
return null;
}


public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return true;
}


}



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值