国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring Secutity 自定義權(quán)限配置

animabear / 2018人閱讀

摘要:實現(xiàn)了接口,用于存放用戶信息與權(quán)限在身份認證中的作用中進行身份驗證的是接口,是它的一個默認實現(xiàn),但它并不用來處理身份認證,而是委托給配置好的,每個會輪流檢查身份認證。檢查后或者返回對象或者拋出異常。另外自定義接口,實現(xiàn)類為。

Srping Security網(wǎng)上也有很多例子,但基本都是所資源直接配置在XML文件里,限制太大,不夠靈活。我們需要的是可以在后臺修改資源訪問權(quán)限,實時生效,才能符合現(xiàn)在大多數(shù)系統(tǒng)的需求。

需要引入的依賴
    
    
        org.springframework.security
        spring-security-web
        4.2.2.RELEASE
    
    
        org.springframework.security
        spring-security-config
        4.2.2.RELEASE
    
    
用戶身份認證

我們自定義一個實現(xiàn)類MUserDetailsService 來實現(xiàn)UserDetailsService接口。

其中需要實現(xiàn)一個loadUserByUsername方法,用來讀取用戶的角色。
在這里需要從數(shù)據(jù)庫中通過用戶名來查詢用戶的信息和用戶所屬的角色
其中MGrantedAuthority實現(xiàn)了GrantedAuthority接口,用于構(gòu)建用戶權(quán)限。
MUserDeatils實現(xiàn)了UserDeatils接口,用于存放用戶信息與權(quán)限

UserDetailsService在身份認證中的作用

Spring Security中進行身份驗證的是AuthenticationManager接口,ProviderManager是它的一個默認實現(xiàn),但它并不用來處理身份認證,而是委托給配置好的AuthenticationProvider,每個AuthenticationProvider會輪流檢查身份認證。檢查后或者返回Authentication對象或者拋出異常。驗證身份就是加載響應(yīng)的UserDetails,看看是否和用戶輸入的賬號、密碼、權(quán)限等信息匹配。此步驟由實現(xiàn)AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService驗證用戶名、密碼和授權(quán))處理。包含 GrantedAuthority 的 UserDetails對象在構(gòu)建 Authentication對象時填入數(shù)據(jù)。

MUserDetailsService.class中的loadUserByUsername方法
    /**
     * 根據(jù)用戶名加載用戶密碼與權(quán)限信息
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //查詢用戶信息
        User user = userMapper.selectByName(username);
        List roleList = null;
        MUserDeatils userDeatils = null;
        if (user != null){
            //查詢用戶的角色
            roleList = roleMapper.queryByUser(user.getId());
            System.out.println("user" + user.getUsername() + "----" + user.getPassword());
            // 構(gòu)建權(quán)限
            Set authorities = new HashSet();
            if (roleList.size() != 0){
                for (Role role: roleList){
                    authorities.add(new MGrantedAuthority(role.getName()));
                    System.out.println(role.getName());
                }
                userDeatils = new MUserDeatils(user.getUsername(),user.getPassword(),authorities);

            }
        }
        return userDeatils;

    }
MGrantedAuthority.class
public class MGrantedAuthority implements GrantedAuthority {

    private String authority;

    public MGrantedAuthority(String authority){
        this.authority = authority;
    }

    @Override
    public String getAuthority() {
        return authority;
    }
}
MUserDeatils.class

實現(xiàn)UserDetails接口定義好變量即可

讀取資源與所屬角色

需要自定義實現(xiàn)類實現(xiàn)FilterInvocationSecurityMetadataSource接口。通過loadResourceDefine方法可以實現(xiàn)資源與權(quán)限的對應(yīng)關(guān)系。

要使我們自定義的MFilterInvocationSecurityMetadataSource生效,我們還需要定義一個MyFilterSecurityInterceptor類。
這里的數(shù)據(jù)需要從數(shù)據(jù)庫中取得。另外自定義接口UrlMatcher,實現(xiàn)類為AntUrlPathMatcher。

網(wǎng)上有教程是把loadResourceDefine方法放在了構(gòu)造函數(shù)里。但我經(jīng)過多次試驗均出現(xiàn)service,mapper無法注入的問題,然后就會報一個空指針的導(dǎo)異常,經(jīng)debug發(fā)現(xiàn)是service沒有注入。經(jīng)多次查詢得知:原因是構(gòu)造方法會先于注入執(zhí)行,所以loadResourceDefine方法放入構(gòu)造中執(zhí)行時函數(shù)內(nèi)的service與mapper還未執(zhí)行注入,因此報 java.lang.NullPointerException的異常。解決方法是將loadResourceDefine方法放在getAttributes方法中執(zhí)行。

MFilterInvocationSecurityMetadataSource.class
    @Component
    public class MFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    @Autowired
    public IRescAndRoleService iRescAndRoleService ;
    @Autowired
    private IUserService iUserService ;
    private UrlMatcher urlMatcher = new AntUrlPathMatcher();
    // 資源權(quán)限集合
    private static Map> resourceMap = null;
    public void loadResourceDefine(){
        resourceMap = new HashMap>();
        //取得用戶信息
        List userList = iUserService.query();
       //取得資源與角色列表
        List resourceList = iRescAndRoleService.query();
        System.out.println(resourceList);
        for (RescAndRole resource : resourceList) {
            Collection atts = new ArrayList();
            atts.add(new SecurityConfig(resource.getRoleName() ));
            resourceMap.put(resource.getResString(), atts);
        }
    }
    @Override
    public Collection getAttributes(Object o) throws IllegalArgumentException {
        loadResourceDefine();//防止無法注入問題
        // guess object is a URL.
        String url = ((FilterInvocation) o).getRequestUrl();
        Iterator ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
            String resURL = ite.next();
            if (urlMatcher.pathMatchesUrl(resURL, url)) {
                return resourceMap.get(resURL);
            }
        }
        return null;
    }
    @Override
    public Collection getAllConfigAttributes() {
        return null;
    }
    @Override
    public boolean supports(Class aClass) {
        return true;
    }
}
AntUrlPathMatcher.class
public class AntUrlPathMatcher implements UrlMatcher {

    private boolean requiresLowerCaseUrl;
    private PathMatcher pathMatcher;

    public AntUrlPathMatcher() {
        this(true);
    }

    public AntUrlPathMatcher(boolean requiresLowerCaseUrl) {
        this.requiresLowerCaseUrl = true;
        this.pathMatcher = new AntPathMatcher();

        this.requiresLowerCaseUrl = requiresLowerCaseUrl;
    }

    public Object compile(String path) {
        if (this.requiresLowerCaseUrl) {
            return path.toLowerCase();
        }
        return path;
    }

    public void setRequiresLowerCaseUrl(boolean requiresLowerCaseUrl) {
        this.requiresLowerCaseUrl = requiresLowerCaseUrl;
    }

    public boolean pathMatchesUrl(Object path, String url) {
        if (("/**".equals(path)) || ("**".equals(path))) {
            return true;
        }
        return this.pathMatcher.match((String) path, url);
    }

    public String getUniversalMatchPattern() {
        return "/**";
    }

    public boolean requiresLowerCaseUrl() {
        return this.requiresLowerCaseUrl;
    }

    public String toString() {
        return super.getClass().getName() + "[requiresLowerCase=""
                + this.requiresLowerCaseUrl + ""]";
    }
}
MyFilterSecurityInterceptor.class
public class MyFilterSecurityInterceptor 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 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);
        }
    }

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

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

    public void destroy() {
    }

    public void init(FilterConfig arg0) throws ServletException {
    }

}
決策管理器

自定義一個決策管理器MyAccessDecisionManager實現(xiàn)AccessDecisionManager接口。其中的decide方法,決定某一個用戶是否有權(quán)限訪問某個url

/* (non-Javadoc)
     * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
     * 該方法決定該權(quán)限是否有權(quán)限訪問該資源,其實object就是一個資源的地址,authentication是當前用戶的
     * 對應(yīng)權(quán)限,如果沒登陸就為游客,登陸了就是該用戶對應(yīng)的權(quán)限
     */
    @Override
    public void decide(Authentication authentication, Object object,
                       Collection configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException {
        if(configAttributes == null) {
            return;
        }
        System.out.println(object.toString()); // object is a URL.
        //所請求的資源擁有的權(quán)限(一個資源對多個權(quán)限)
        Iterator iterator = configAttributes.iterator();
        while(iterator.hasNext()) {
            ConfigAttribute configAttribute = iterator.next();
            //訪問所請求資源所需要的權(quán)限
            String needPermission = configAttribute.getAttribute();
            System.out.println("訪問"+object.toString()+"需要的權(quán)限是:" + needPermission);
            //用戶所擁有的權(quán)限authentication
            Collection authorities = authentication.getAuthorities();
            for(GrantedAuthority ga : authorities) {
                if(needPermission.equals(ga.getAuthority())) {
                    return;
                }
            }
        }
        //沒有權(quán)限
        throw new AccessDeniedException(" 沒有權(quán)限訪問! ");
    }

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

    @Override
    public boolean supports(Class clazz) {
        // TODO Auto-generated method stub
        return true;
    }
配置XML web.xml

添加Seucrity的過濾器,將攔截所有資源訪問

注意
    只能配置成 /*
    
    
    
        contextConfigLocation
        
            WEB-INF/config/security.xml
            WEB-INF/config/spring-mybatis.xml
        
    
    
    
    
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
    
    
        springSecurityFilterChain
        /*
    
spring-security.xml



    
    
    
    
    
    
    
    
    
    
    

        
        
        
        
        
        
        
        

    

    
    
        
        
        
        
        
        
        
    

    
    
        
            
        
    

    
    

    
    

    
    

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67422.html

相關(guān)文章

  • 基于 Spring Session & Spring Security 微服務(wù)權(quán)限控制

    摘要:構(gòu)造函數(shù)的第一個參數(shù)是對象,所以可以自定義緩存對象。在微服務(wù)各個模塊獲取用戶的這些信息的方法如下略權(quán)限控制啟用基于方法的權(quán)限注解簡單權(quán)限校驗例如,刪除角色的接口,僅允許擁有權(quán)限的用戶訪問。 showImg(https://segmentfault.com/img/remote/1460000019593311); 微服務(wù)架構(gòu) showImg(https://segmentfault.c...

    clasnake 評論0 收藏0
  • Shiro【授權(quán)、整合Spirng、Shiro過濾器】

    摘要:表示對用戶資源進行操作,相當于,對所有用戶資源實例進行操作。與整合,實際上的操作都是通過過濾器來干的。將安全管理器交由工廠來進行管理。在過濾器鏈中設(shè)置靜態(tài)資源不攔截。 前言 本文主要講解的知識點有以下: Shiro授權(quán)的方式簡單介紹 與Spring整合 初始Shiro過濾器 一、Shiro授權(quán) 上一篇我們已經(jīng)講解了Shiro的認證相關(guān)的知識了,現(xiàn)在我們來弄Shiro的授權(quán) Shir...

    ralap 評論0 收藏0
  • Spring Security 進階-細節(jié)總結(jié)

    摘要:但是我們最好不要在里面對他進行處理,而是放到配置的權(quán)限異常來處理。記得配置登錄認證前和過程中的一些請求不需要身份認證。登錄認證失敗不能直接拋出錯誤,需要向前端響應(yīng)異常。 關(guān)于 Spring Security 的學(xué)習(xí)已經(jīng)告一段落了,剛開始接觸該安全框架感覺很迷茫,總覺得沒有 Shiro 靈活,到后來的深入學(xué)習(xí)和探究才發(fā)現(xiàn)它非常強大。簡單快速集成,基本不用寫任何代碼,拓展起來也非常靈活和強...

    LinkedME2016 評論0 收藏0
  • 不用 Spring Security 可否?試試這個小而美的安全框架

    摘要:寫在前面在一款應(yīng)用的整個生命周期,我們都會談及該應(yīng)用的數(shù)據(jù)安全問題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。 寫在前面 在一款應(yīng)用的整個生命周期,我們都會談及該應(yīng)用的數(shù)據(jù)安全問題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。但是,一方面,不同的應(yīng)用對于數(shù)據(jù)的合法性和可見性要求的維度與粒度都有所區(qū)別;另一方面,以當前微服務(wù)、多服務(wù)的架構(gòu)方式,如何共享Sessi...

    toddmark 評論0 收藏0
  • 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》

    摘要:下一代服務(wù)端開發(fā)下一代服務(wù)端開發(fā)第部門快速開始第章快速開始環(huán)境準備,,快速上手實現(xiàn)一個第章企業(yè)級服務(wù)開發(fā)從到語言的缺點發(fā)展歷程的缺點為什么是產(chǎn)生的背景解決了哪些問題為什么是的發(fā)展歷程容器的配置地獄是什么從到下一代企業(yè)級服務(wù)開發(fā)在移動開發(fā)領(lǐng)域 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》 Kotlin + Spring Boot : 下一代 Java...

    springDevBird 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<