2012-07-26 54 views
6

當前我正在使用spring security和@PreAuthorize註釋來保護方法調用。現在我想改變一個方法調用的認證標記,就像Spring安全允許我做的run-as authentication replacement一樣。用spring-security更改方法調用的安全上下文

我可以在每個方法基礎上配置替換嗎?每註釋,SpEL表達式.... 如果沒有,是否有可能在runAsManager中計算出哪種方法被調用? 我將如何配置安全對象的安全配置屬性?

回答

1

我通過實現我自己的RunAsManager解決了這個問題,它檢查被調用方法上的自定義註釋並返回相應的令牌。

很好用。

6

我已經發布a detailed article實施運行與@PreAuthorize結合。

1)實現您自己的RunAsManager,創建Authentication以在基於任何自定義邏輯的方法執行期間使用。下面的示例使用自定義註釋提供額外的角色:

public class AnnotationDrivenRunAsManager extends RunAsManagerImpl { 

     @Override 
     public Authentication buildRunAs(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { 
      if(!(object instanceof ReflectiveMethodInvocation) || ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class) == null) { 
       return super.buildRunAs(authentication, object, attributes); 
      } 

      String roleName = ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class).value(); 

      if (roleName == null || roleName.isEmpty()) { 
       return null; 
      } 

      GrantedAuthority runAsAuthority = new SimpleGrantedAuthority(roleName); 
      List<GrantedAuthority> newAuthorities = new ArrayList<GrantedAuthority>(); 
      // Add existing authorities 
      newAuthorities.addAll(authentication.getAuthorities()); 
      // Add the new run-as authority 
      newAuthorities.add(runAsAuthority); 

      return new RunAsUserToken(getKey(), authentication.getPrincipal(), authentication.getCredentials(), 
        newAuthorities, authentication.getClass()); 
     } 
    } 

此實現將尋找一個自定義@RunAsRole標註在受保護的方法(如@RunAsRole("ROLE_AUDITOR")),如有發現,將添加特定機構(ROLE_AUDITOR在本案)列入授權機構名單。 RunAsRole本身只是一個簡單的自定義註釋。

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface RunAsRole { 
    String value(); 
} 

2)實例化管理器:

<bean id="runAsManager" 
    class="org.springframework.security.access.intercept.RunAsManagerImpl"> 
    <property name="key" value="my_run_as_key"/> 
</bean> 

3)註冊它:

<global-method-security pre-post-annotations="enabled" run-as-manager-ref="runAsManager"> 
    <expression-handler ref="expressionHandler"/> 
</global-method-security> 

4)實施例的使用在控制器:

@Controller 
public class TransactionLogController { 

    @PreAuthorize("hasRole('ROLE_REGISTERED_USER')") //Authority needed to access the method 
    @RunAsRole("ROLE_AUDITOR") //Authority added by RunAsManager 
    @RequestMapping(value = "/transactions", method = RequestMethod.GET) //Spring MVC configuration. Not related to security 
    @ResponseBody //Spring MVC configuration. Not related to security 
    public List<Transaction> getTransactionLog(...) { 
    ... //Invoke something in the backend requiring ROLE_AUDITOR 
    { 

    ... //User does not have ROLE_AUDITOR here 
} 

編輯:RunAsManagerImpl中的值可以是任何你想要的。下面是Spring docs其使用的摘錄:

爲了確保惡意代碼不會創建一個關鍵的RunAsUserToken和現在 它保證接受的RunAsImplAuthenticationProvider, 散列被存儲在所有生成的標記。該 RunAsManagerImplRunAsImplAuthenticationProvider在 豆上下文中創建具有相同的鍵:

<bean id="runAsManager" 
    class="org.springframework.security.access.intercept.RunAsManagerImpl"> 

<bean id="runAsAuthenticationProvider" 
    class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> 

通過使用 相同的密鑰,每個RunAsUserToken可以驗證它的創建由 批准RunAsManagerImpl。出於安全原因,創建 之後RunAsUserToken是不可變的。

+0

「my_run_as_key」的用途是什麼? - 我無法弄清楚。我可能讀過你在這裏引用的同一個指南,但這個關鍵對我沒有任何意義。 – 2016-12-12 11:07:39

+0

@DanielBo值可以是任何你想要的。它基本上是一個密碼。 我更新了爲什麼需要引用Spring文檔的答案。 – kaqqao 2016-12-12 14:34:27

相關問題