spring security的简单使用

       做权限管理的时候学习了security的使用,包括官方的使用配置示例,学习新东西的时候最好参照官方的使用文档,英文的也好,纵使英文不好,慢慢阅读,养成好习惯,自己的英文水平也会慢慢提高,搞开发英文水平也是很重要的。

     首先引入security所需的包,工程使用maven构建,控制某个用户是否有对资源的访问权限

<!--security-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>3.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-cas</artifactId>
            <version>3.1.3.RELEASE</version>
        </dependency>

在web.xml中配置过滤器,引入security的配置文件,配置过滤器时注意名字springSecurityFilterChain

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/applicationContext.xml,classpath:/spring/application-security.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>

在applicationContext-security.xml使用命名空间配置

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	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.2.xsd">
<intercept-url pattern="/login.jsp" filters="none"/>//默认login.jsp不拦截
<form-login login-page="/login.jsp" authentication-failure-url="/403.jsp" default-target-url="/index.jsp"/>//自定义登录界面
<http-basic/>
<logout logout-success-url="/login.jsp"/>
<http pattern="/js/**" security="none"/>
<http pattern="/css/**" security="none"></http>
<http pattern="/login.jsp" security="none"/>
<http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
<logout/>
<remember-me />
        <session-management invalid-session-url="/timeout.jsp">
            <concurrency-control max-sessions="30" error-if-maximum-exceeded="true" />
        </session-management>
<custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER"  />
<custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/><!-- 自定义filter在默认过滤器之前 -->
</http>
<beans:bean id="loginFilter"
		class="com.amplesky.security.MyUsernamePasswordAuthenticationFilter">
		<!-- 处理登录 -->
		<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
		<beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property>
		<beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property>
		<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean>
<beans:bean id="loginLogAuthenticationSuccessHandler"
		class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
		<beans:property name="defaultTargetUrl" value="/index.jsp"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
		class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
		<beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property>
</beans:bean>

 <!-- 用户自定义filter必须包含三个属性 -->
<beans:bean id="myFilter" class="com.amplesky.security.MySecurityFilter">
 <!-- 用户拥有的权限 -->
 <beans:property name="authenticationManager" ref="myAuthenticationManager"/>
 <!-- 用户是否用户访问资源的权限-->
 <beans:property name="accessDecisionManager" ref="myAccessDecisionManager"/>
  <!-- 资源与权限的关系-->
 <beans:property name="securityMedataSource" ref="mySecurityMetadataSource"/>
</beans:bean>
<!-- 认证管理器,实现UsersDetailsService接口 -->
<authentication-manager alias="myAuthenticationManager">
  <authentication-provider user-service-ref="myUserDetailServiceImpl"/>
</authentication-manager>					 
<!-- 访问决策层,决定某个用户具有的角色,是否有足够角色访问某个资源 -->
<beans:bean id="myAccessDecisionManager" class="com.amplesky.security.MyAccessDecisionManager">
</beans:bean>
<!-- 资源数据定义,定义某一资源能被那些角色访问 -->
<beans:bean id="mySecurityMetadataSource" class="com.amplesky.security.MySecurityMetadataSource" init-method="loadResourceDefine">
</beans:bean>
<!-- service -->
<beans:bean id="myUserDetailServiceImpl" class="com.amplesky.security.MyUserDetailServiceImpl">
</beans:bean>
<!-- 未登录的切入点 -->
<beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"></beans:property>
</beans:bean>
</beans:beans>
定义三个对象,五张表

User.java   Role.java   Resource.java

T_User表

用于存放用户信息,此处只存放基础信息


T_Role表

用于存放系统角色信息

T_User_Role表

用于存放系统用户与角色的匹配关系


T_Resource表

用于存放资源表

T_Role_Resource表

存放角色对应的资源表


 登录页面form提交的路径

 <form action="j_spring_security_check" method="post">
登录处理的filter
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
	public static final String VALIDATE_CODE = "validateCode";
	public static final String USERNAME = "username";
	public static final String PASSWORD = "password";
	@Resource
	private LoginDao loginDao;
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		//验证用户账号与密码是否对应
		username = username.trim();	
		Users users = this.loginDao.findByName(username);	
		if(users == null || !users.getPassword().equals(password)) {
	/* 
		if (forwardToDestination) {
            request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
        } else {
            HttpSession session = request.getSession(false);

            if (session != null || allowSessionCreation) {
                request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
            }
        }
	 */
			throw new AuthenticationServiceException("password or username is notEquals"); 
		}
		
		//UsernamePasswordAuthenticationToken实现 Authentication
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
		// Place the last username attempted into HttpSession for views
		
		// 允许子类设置详细属性
        setDetails(request, authRequest);
		
        // 运行UserDetailsService的loadUserByUsername 再次封装Authentication
		return this.getAuthenticationManager().authenticate(authRequest);
	}
	
	}
	
MyUserDetailServiceIMpl.java

public class MyUserDetailServiceImpl implements UserDetailsService{
   @Resource
   private LoginDao loginDao;
	@Override
	public UserDetails loadUserByUsername(String usersname) {
		// TODO Auto-generated method stub
		System.out.println("Usersname is:"+usersname);
		Users Users=this.loginDao.findByName(usersname);
		Collection<GrantedAuthority> grantedAuths=obtionGrantedAuthorities(this.loginDao.findByName(usersname));
		boolean enables = true;  
       		boolean accountNonExpired = true;  
     		boolean credentialsNonExpired = true;  
      		boolean accountNonLocked = true;  
       		User Usersdetail=new User(Users.getLoginId(),Users.getPassword(),enables, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths);
		return Usersdetail;
	}
	//取得用户权限
	public Set<GrantedAuthority> obtionGrantedAuthorities(Users user){
		  Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();  
		         Set<Role> roles = loginDao.findRoleByUsers(user); //根据用户取得用户的角色 	           
		         for(Role role : roles) {  
		            	 authSet.add(new GrantedAuthorityImpl(role.getRoleName()));  
		            }      
		
		        return authSet;  
		     }  
	}
MySecurityMetadaSource.java //加载所有的资源和权限关系
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource{
    @Resource(name="resourceDao")
    private ResourceDao resourceDao;
    public void setResourceDao(ResourceDao resourceDao){
    	this.resourceDao=resourceDao;
    }
	private static Map<String,Collection<ConfigAttribute>> resourceMap=null;
   //加载所有的资源和权限关系
	public  void loadResourceDefine(){
    	if(resourceMap==null){
    		resourceMap=new HashMap<String,Collection<ConfigAttribute>>();
    		List<Resource> list=resourceDao.getResourceAll();
    		for(Resource functionTree:list){
    			Collection<ConfigAttribute> configAttributes=new ArrayList<ConfigAttribute>();
    			List<Role> roles=resourceDao.getRoleByFunc(functionTree);//根据资源得到需要的角色
    			for(Role role:roles){
    				ConfigAttribute configAttribute=new SecurityConfig(role.getRoleName());
    				configAttributes.add(configAttribute);
    			}
    			resourceMap.put(functionTree.getUrl(), configAttributes);			
    		}
    	}  	
    	  Set<Map.Entry<String, Collection<ConfigAttribute>>> resourceSet = resourceMap.entrySet();  
    	  Iterator<Map.Entry<String, Collection<ConfigAttribute>>> iterator = resourceSet.iterator(); 
    }
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// TODO Auto-generated method stub
		return null;
	}
//返回请求资源所需的权限
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		// TODO Auto-generated method stub
		String requestUrl=((FilterInvocation)object).getRequestUrl();
		System.out.println("request url is"+requestUrl);
		if(resourceMap==null){
			loadResourceDefine();
		}
		return resourceMap.get(requestUrl);
	}

	@Override
	public boolean supports(Class<?> arg0) {
		// TODO Auto-generated method stub
		return true;
	}
	public static Map<String,Collection<ConfigAttribute>> getResourceMap() {
		return resourceMap;
	}
	public static void setResourceMap(Map<String,Collection<ConfigAttribute>> resourceMap) {
		MySecurityMetadataSource.resourceMap = resourceMap;
	}

}
MyAccessDecisionManager.java  //访问决策层,决定某个用户具有的角色,是否有足够角色访问某个资源

public class MyAccessDecisionManager implements AccessDecisionManager{

	@Override
	public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttribute) throws AccessDeniedException,
			InsufficientAuthenticationException {
		// TODO Auto-generated method stub
			if(configAttribute==null){
				return;
			}
			Iterator<ConfigAttribute> iterator=configAttribute.iterator();
			while(iterator.hasNext()){
				ConfigAttribute configAttr=iterator.next();
				String needPermission=configAttr.getAttribute();
				System.out.println(needPermission+">>>>>>");
				for(GrantedAuthority ga:authentication.getAuthorities()){
					if(needPermission.equals(ga.getAuthority())){//判断需要的角色名是否和用户的角色名相同,否则没有权限
						return;
					}
				}
			}
	        throw new AccessDeniedException(" 没有权限访问! ");  
			
	}

	@Override
	public boolean supports(ConfigAttribute arg0) {
		// TODO Auto-generated method stub
		return true;
	}

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

MySecurityFilter.java //用户自定义filter

public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter{
	
	private FilterInvocationSecurityMetadataSource securityMedataSource;
	public void setSecurityMedataSource(
			FilterInvocationSecurityMetadataSource securityMedataSource) {
		this.securityMedataSource = securityMedataSource;
	}

	@Override
	public Class<? extends Object> getSecureObjectClass() {
		// TODO Auto-generated method stub
		return FilterInvocation.class;
	}

	@Override
	public SecurityMetadataSource obtainSecurityMetadataSource() {
		// TODO Auto-generated method stub
		return this.securityMedataSource;
	}
	private void invoke(FilterInvocation fi){
		InterceptorStatusToken token=super.beforeInvocation(fi);
		try{
			fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			super.afterInvocation(token, null);
		}	
	}
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		FilterInvocation fi=new FilterInvocation(request,response,chain);
		invoke(fi);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}	

}
  至此,简单的权限控制完成了,判断用户是否对某个资源具有访问权限,否则提示没有权限访问。





        


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值