橘子味阳光 2016-12-16 07:07 采纳率: 16.7%
浏览 3903
已结题

FilterInvocationSecurityMetadataSource不执行

FilterInvocationSecurityMetadataSource中的getAttributes 不执行
AccessDecisionManagerye也不执行

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/home").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage("/login")    
        .permitAll()
        .successHandler(loginSuccessHandler())//code3
        .and()
        .logout()
        .logoutSuccessUrl("/home")
        .permitAll()
        .invalidateHttpSession(true)
        .and()
        .rememberMe()
        .tokenValiditySeconds(1209600);
    }
 @Service
public class CustomInvocationSecurityMetadataSourceService implements
        FilterInvocationSecurityMetadataSource {

    private SResourceService sResourceService;

    private SRoleService sRoleService;

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    public CustomInvocationSecurityMetadataSourceService(SResourceService sres,SRoleService sR) {
        this.sResourceService = sres;
        this.sRoleService = sR;
        loadResourceDefine();
    }

    private void loadResourceDefine() {
        List<String> query =sRoleService.findByAll();

        /*
         * 应当是资源为key, 权限为value。 资源通常为url, 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。
         * sparta
         */
        resourceMap = new HashMap<String, Collection<ConfigAttribute>>();

        for (String auth : query) {
            ConfigAttribute ca = new SecurityConfig(auth);
            List<String> query1 = sResourceService.findByRoleName(auth);
            for (String res : query1) {
                String url = res;

                /*
                 * 判断资源文件和权限的对应关系,如果已经存在相关的资源url,则要通过该url为key提取出权限集合,将权限增加到权限集合中。
                 * sparta
                 */
                if (resourceMap.containsKey(url)) {

                    Collection<ConfigAttribute> value = resourceMap.get(url);
                    value.add(ca);
                    resourceMap.put(url, value);
                } else {
                    Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
                    atts.add(ca);
                    resourceMap.put(url, atts);
                }

            }

        }

    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        System.out.println("sdfafgaferfgagaergsrtgsrtgsrtger");
        return null;
    }

    // 根据URL,找到相关的权限配置。
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        System.out.println("dfergwerheyjhyrururuyjr67"+object);
        // object 是一个URL,被用户请求的url。
        FilterInvocation filterInvocation = (FilterInvocation) object;

        Iterator<String> ite = resourceMap.keySet().iterator();

        while (ite.hasNext()) {
            String resURL = ite.next();
            System.out.println("urlurlurluuuuuuuu"+resURL);
              RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);
                if(requestMatcher.matches(filterInvocation.getHttpRequest())) {
                if (resourceMap == null) {
                    loadResourceDefine();
                }
                return resourceMap.get(resURL);
            }
        }
         if (resourceMap == null) {
              loadResourceDefine();
         }
         return resourceMap.get("/hello");
    }

    @Override
    public boolean supports(Class<?> arg0) {

        return true;
    }

}

 /*
 * @(#) MyFilterSecurityInterceptor.java  2011-3-23 上午07:53:03
 *
 * Copyright 2011 by Sparta 
 */

package cn.paybay.ticketManager.support.authentication;

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;

/**
 * 该过滤器的主要作用就是通过spring著名的IoC生成securityMetadataSource。
 * securityMetadataSource相当于本包中自定义的MyInvocationSecurityMetadataSourceService。
 * 该MyInvocationSecurityMetadataSourceService的作用提从数据库提取权限和资源,装配到HashMap中,
 * 供Spring Security使用,用于权限校验。
 * @author sparta 11/3/29
 *
 */

public class CustomFilterSecurityInterceptor 
    extends AbstractSecurityInterceptor
    implements Filter{


    private FilterInvocationSecurityMetadataSource securityMetadataSource;

    public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException{

        FilterInvocation fi = new FilterInvocation( request, response, chain );
        invoke(fi);

    }

    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource(){
        return this.securityMetadataSource;
    }

    public Class<? extends Object> getSecureObjectClass(){
        return FilterInvocation.class;
    }


    public void invoke( FilterInvocation fi ) throws IOException, ServletException{

        InterceptorStatusToken  token = super.beforeInvocation(fi);

        try{
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        }finally{
            super.afterInvocation(token, null);
        }

    }


    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource(){
        return this.securityMetadataSource;
    }


    public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource){
        this.securityMetadataSource = securityMetadataSource;
    }


    public void destroy(){

    }

    public void init( FilterConfig filterconfig ) throws ServletException{

    }


}

 /*
 * @(#) MyAccessDecisionManager.java  2011-3-23 下午04:41:12
 *
 * Copyright 2011 by Sparta 
 */

package cn.paybay.ticketManager.support.authentication;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

/**
 *AccessdecisionManager在Spring security中是很重要的。
 *
 *在验证部分简略提过了,所有的Authentication实现需要保存在一个GrantedAuthority对象数组中。 
 *这就是赋予给主体的权限。 GrantedAuthority对象通过AuthenticationManager
 *保存到 Authentication对象里,然后从AccessDecisionManager读出来,进行授权判断。 
 *
 *Spring Security提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。 
 *一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。 
 *这个 AccessDecisionManager 被AbstractSecurityInterceptor调用,
 *它用来作最终访问控制的决定。 这个AccessDecisionManager接口包含三个方法: 
 *
 void decide(Authentication authentication, Object secureObject,
    List<ConfigAttributeDefinition> config) throws AccessDeniedException;
 boolean supports(ConfigAttribute attribute);
 boolean supports(Class clazz);

  从第一个方法可以看出来,AccessDecisionManager使用方法参数传递所有信息,这好像在认证评估时进行决定。 
  特别是,在真实的安全方法期望调用的时候,传递安全Object启用那些参数。 
  比如,让我们假设安全对象是一个MethodInvocation。 
  很容易为任何Customer参数查询MethodInvocation,
  然后在AccessDecisionManager里实现一些有序的安全逻辑,来确认主体是否允许在那个客户上操作。 
  如果访问被拒绝,实现将抛出一个AccessDeniedException异常。

  这个 supports(ConfigAttribute) 方法在启动的时候被
  AbstractSecurityInterceptor调用,来决定AccessDecisionManager
  是否可以执行传递ConfigAttribute。 
  supports(Class)方法被安全拦截器实现调用,
  包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。
 */
public class CustomAccessDecisionManager implements AccessDecisionManager {

    public void decide( Authentication authentication, Object object, 
            Collection<ConfigAttribute> configAttributes) 
        throws AccessDeniedException, InsufficientAuthenticationException{
        System.out.println("dededededededededededede");
        if( configAttributes == null ) {
            return ;
        }

        Iterator<ConfigAttribute> ite = configAttributes.iterator();

        while( ite.hasNext()){

            ConfigAttribute ca = ite.next();
            String needRole = ((SecurityConfig)ca).getAttribute();

            //ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。
            for( GrantedAuthority ga: authentication.getAuthorities()){

                if(needRole.trim().equals(ga.getAuthority().trim())){

                    return;
                }

            }

        }

        throw new AccessDeniedException("");

    }

    public boolean supports( ConfigAttribute attribute ){

        return true;

    }

    public boolean supports(Class<?> clazz){
        return true;

    }


}

  • 写回答

1条回答 默认 最新

  • 让我发会呆 2016-12-16 08:16
    关注

    在博客园看到你这个问题,现在又……,
    我们项目也用了Spring security,不过我只会在xml里做一些基本的配置使用,话说filter都是在web.xml里配置的

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)