真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java中如何實(shí)現(xiàn)自定義SpringSecurity權(quán)限

今天就跟大家聊聊有關(guān)java中如何實(shí)現(xiàn)自定義Spring Security權(quán)限,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)公司專(zhuān)業(yè)為企業(yè)提供永濟(jì)網(wǎng)站建設(shè)、永濟(jì)做網(wǎng)站、永濟(jì)網(wǎng)站設(shè)計(jì)、永濟(jì)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、永濟(jì)企業(yè)網(wǎng)站模板建站服務(wù),10余年永濟(jì)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

背景描述

項(xiàng)目中需要做細(xì)粒的權(quán)限控制,細(xì)微至url + httpmethod (滿足restful,例如: https://.../xxx/users/1, 某些角色只能查看(HTTP GET), 而無(wú)權(quán)進(jìn)行增改刪(POST, PUT, DELETE))。

表設(shè)計(jì)

為避嫌,只列出要用到的關(guān)鍵字段,其余敬請(qǐng)自行腦補(bǔ)。

1.admin_user 管理員用戶(hù)表, 關(guān)鍵字段( id, role_id )。

2.t_role 角色表, 關(guān)鍵字段( id, privilege_id )。

3.t_privilege 權(quán)限表, 關(guān)鍵字段( id, url, method )

三個(gè)表的關(guān)聯(lián)關(guān)系就不用多說(shuō)了吧,看字段一眼就能看出。

實(shí)現(xiàn)前分析

我們可以逆向思考:

要實(shí)現(xiàn)我們的需求,最關(guān)鍵的一步就是讓Spring Security的AccessDecisionManager來(lái)判斷所請(qǐng)求的url + httpmethod 是否符合我們數(shù)據(jù)庫(kù)中的配置。然而,AccessDecisionManager并沒(méi)有來(lái)判定類(lèi)似需求的相關(guān)Voter, 因此,我們需要自定義一個(gè)Voter的實(shí)現(xiàn)(默認(rèn)注冊(cè)的AffirmativeBased的策略是只要有Voter投出ACCESS_GRANTED票,則判定為通過(guò),這也正符合我們的需求)。實(shí)現(xiàn)voter后,有一個(gè)關(guān)鍵參數(shù)(Collection

總結(jié)一下思路步驟:

1.自定義voter實(shí)現(xiàn)。

2.自定義ConfigAttribute實(shí)現(xiàn)。

3.自定義SecurityMetadataSource實(shí)現(xiàn)。

4.Authentication包含用戶(hù)實(shí)例(這個(gè)其實(shí)不用說(shuō),大家應(yīng)該都已經(jīng)這么做了)。

5.自定義GrantedAuthority實(shí)現(xiàn)。

項(xiàng)目實(shí)戰(zhàn)

1.自定義GrantedAuthority實(shí)現(xiàn)

UrlGrantedAuthority.java

public class UrlGrantedAuthority implements GrantedAuthority {

  private final String httpMethod;

  private final String url;

  public UrlGrantedAuthority(String httpMethod, String url) {
    this.httpMethod = httpMethod;
    this.url = url;
  }

  @Override
  public String getAuthority() {
    return url;
  }

  public String getHttpMethod() {
    return httpMethod;
  }

  public String getUrl() {
    return url;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    UrlGrantedAuthority target = (UrlGrantedAuthority) o;
    if (httpMethod.equals(target.getHttpMethod()) && url.equals(target.getUrl())) return true;
    return false;
  }

  @Override
  public int hashCode() {
    int result = httpMethod != null ? httpMethod.hashCode() : 0;
    result = 31 * result + (url != null ? url.hashCode() : 0);
    return result;
  }
}

2.自定義認(rèn)證用戶(hù)實(shí)例

public class SystemUser implements UserDetails {

  private final Admin admin;

  private List menuOutputList;

  private final List grantedAuthorities;

  public SystemUser(Admin admin, List grantedPrivileges, List menuOutputList) {
    this.admin = admin;
    this.grantedAuthorities = grantedPrivileges.stream().map(it -> {
      String method = it.getMethod() != null ? it.getMethod().getLabel() : null;
      return new UrlGrantedAuthority(method, it.getUrl());
    }).collect(Collectors.toList());
    this.menuOutputList = menuOutputList;
  }

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    return this.grantedAuthorities;
  }

  @Override
  public String getPassword() {
    return admin.getPassword();
  }

  @Override
  public String getUsername() {
    return null;
  }

  @Override
  public boolean isAccountNonExpired() {
    return true;
  }

  @Override
  public boolean isAccountNonLocked() {
    return true;
  }

  @Override
  public boolean isCredentialsNonExpired() {
    return true;
  }

  @Override
  public boolean isEnabled() {
    return true;
  }

  public Long getId() {
    return admin.getId();
  }

  public Admin getAdmin() {
    return admin;
  }

  public List getMenuOutputList() {
    return menuOutputList;
  }

  public String getSalt() {
    return admin.getSalt();
  }
}  

3.自定義UrlConfigAttribute實(shí)現(xiàn)

public class UrlConfigAttribute implements ConfigAttribute {

  private final HttpServletRequest httpServletRequest;

  public UrlConfigAttribute(HttpServletRequest httpServletRequest) {
    this.httpServletRequest = httpServletRequest;
  }


  @Override
  public String getAttribute() {
    return null;
  }

  public HttpServletRequest getHttpServletRequest() {
    return httpServletRequest;
  }
}

4.自定義SecurityMetadataSource實(shí)現(xiàn)

public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

  @Override
  public Collection getAttributes(Object object) throws IllegalArgumentException {
    final HttpServletRequest request = ((FilterInvocation) object).getRequest();
    Set allAttributes = new HashSet<>();
    ConfigAttribute configAttribute = new UrlConfigAttribute(request);
    allAttributes.add(configAttribute);
    return allAttributes;
  }

  @Override
  public Collection getAllConfigAttributes() {
    return null;
  }

  @Override
  public boolean supports(Class<?> clazz) {
    return FilterInvocation.class.isAssignableFrom(clazz);
  }

}

5.自定義voter實(shí)現(xiàn)

public class UrlMatchVoter implements AccessDecisionVoter {

 
  @Override
  public boolean supports(ConfigAttribute attribute) {
    if (attribute instanceof UrlConfigAttribute) return true;
    return false;
  }

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

  @Override
  public int vote(Authentication authentication, Object object, Collection attributes) {
    if(authentication == null) {
      return ACCESS_DENIED;
    }
    Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

    for (ConfigAttribute attribute : attributes) {
      if (!(attribute instanceof UrlConfigAttribute)) continue;
      UrlConfigAttribute urlConfigAttribute = (UrlConfigAttribute) attribute;
      for (GrantedAuthority authority : authorities) {
        if (!(authority instanceof UrlGrantedAuthority)) continue;
        UrlGrantedAuthority urlGrantedAuthority = (UrlGrantedAuthority) authority;
        if (StringUtils.isBlank(urlGrantedAuthority.getAuthority())) continue;
        //如果數(shù)據(jù)庫(kù)的method字段為null,則默認(rèn)為所有方法都支持
        String httpMethod = StringUtils.isNotBlank(urlGrantedAuthority.getHttpMethod()) ? urlGrantedAuthority.getHttpMethod()
            : urlConfigAttribute.getHttpServletRequest().getMethod();
        //用Spring已經(jīng)實(shí)現(xiàn)的AntPathRequestMatcher進(jìn)行匹配,這樣我們數(shù)據(jù)庫(kù)中的url也就支持ant風(fēng)格的配置了(例如:/xxx/user/**)    
        AntPathRequestMatcher antPathRequestMatcher = new AntPathRequestMatcher(urlGrantedAuthority.getAuthority(), httpMethod);
        if (antPathRequestMatcher.matches(urlConfigAttribute.getHttpServletRequest()))
          return ACCESS_GRANTED;
      }
    }
    return ACCESS_ABSTAIN;
  }
}

6.自定義FilterSecurityInterceptor實(shí)現(xiàn)

public class UrlFilterSecurityInterceptor extends FilterSecurityInterceptor {

  public UrlFilterSecurityInterceptor() {
    super();
  }

  @Override
  public void init(FilterConfig arg0) throws ServletException {
    super.init(arg0);
  }

  @Override
  public void destroy() {
    super.destroy();
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    super.doFilter(request, response, chain);
  }

  @Override
  public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
    return super.getSecurityMetadataSource();
  }

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

  @Override
  public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource newSource) {
    super.setSecurityMetadataSource(newSource);
  }

  @Override
  public Class<?> getSecureObjectClass() {
    return super.getSecureObjectClass();
  }

  @Override
  public void invoke(FilterInvocation fi) throws IOException, ServletException {
    super.invoke(fi);
  }

  @Override
  public boolean isObserveOncePerRequest() {
    return super.isObserveOncePerRequest();
  }

  @Override
  public void setObserveOncePerRequest(boolean observeOncePerRequest) {
    super.setObserveOncePerRequest(observeOncePerRequest);
  }
}

配置文件關(guān)鍵配置


  ...
  



  



  
    
      
      
      
    
  





  
  
  
 

看完上述內(nèi)容,你們對(duì)java中如何實(shí)現(xiàn)自定義Spring Security權(quán)限有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


新聞標(biāo)題:java中如何實(shí)現(xiàn)自定義SpringSecurity權(quán)限
網(wǎng)站鏈接:http://weahome.cn/article/pooioe.html

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部