4

私はSpring Security OAuth2を使用しています。基本的な構成は問題なく動作しています。私は今誰かがいくつかのエンドポイントにアクセスする権限を持っているかどうかを判断するカスタムロジックを含む別のWebSecurityConfigurerAdapterを持っています。しかし、私が何を試しても実行されません。以下は私のOAuth2構成とトピックに関する私の知見です。認証サーバ:OAuth2リソースサーバーと一緒にカスタムhttpセキュリティー構成

@Configuration 
@EnableAuthorizationServer 
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private TokenStore tokenStore; 

    @Autowired 
    private AuthenticationManagerBuilder authenticationManager; 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)throws Exception { 
     endpoints.authenticationManager(authentication -> authenticationManager.getOrBuild().authenticate(authentication)).tokenStore(tokenStore); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory().withClient("CLIENT_NAME")...; 
    } 

} 

リソースサーバー:これまで

@Configuration 
@EnableResourceServer 
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { 

    @Autowired 
    private TokenStore tokenStore; 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().anyRequest().authenticated(); 
    } 

    @Override 
    public void configure(final ResourceServerSecurityConfigurer resources) throws Exception { 
     resources.tokenStore(tokenStore); 
    } 
} 

とても良いです。カスタムWebSecurityConfigurerAdapterが行動に入ると、私は問題を持ち始めます。 EnableResourceServer注釈付きBeanは、でWebSecurityConfigurerAdapterを作成するので、すべての要求で最初に実行され、ユーザーは正常に認証/承認されますが、WebSecurityConfigurationのカスタムロジックは実行されません。一方、WebSecurityConfigurationOrder(2)以下を設定すると、カスタムaccessのルールが実行されますが、匿名ユーザーからのものであると常に言います(@EnableResourceServerで作成されたBeanのルールは実行されないため)。ただ、サイドノートとして

@EnableWebSecurity 
@Configuration 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Bean 
    public TokenStore tokenStore() { 
     return new InMemoryTokenStore(); 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/..."); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable(); 

     http.authorizeRequests().antMatchers(HttpMethod.GET, "/path/**") 
     .access("@security.hasPermission(authentication, 'SOME', 'VALUE')"); 

     http.authorizeRequests().anyRequest().authenticated(); 
    } 
} 

は、 accessルールで @security参照は、単純な命名のSpring Beanです:

@Component("security") 
public class SecurityService { 
    public boolean hasPermission(Authentication authentication, String param, String anotherParam) { ... } 
} 

私はWebSecurityConfigurationでカスタムアクセスルールを検証する統合テストを持っており、彼らが働きます(私はそこで認証をスキップするので)。私は、認証のためだけにリソースサーバーを使用し、次に承認のための私のカスタムHTTPセキュリティを使用できるようにしたいと思います。

答えて

0

oauth2を使い、最初にトークンを取得してAPIで使用すると(Authorization Bearer [TOKEN]を使用して)、カスタム式を作成するためにロジックを少し変更する必要があります。あなたは春ブーツ1.5以降を使用している場合

まず第一に、あなたのapplication.propertiesファイルに次のプロパティを追加することを検討してください:security.oauth2.resource.filter-order=3今(1.5 release notes

あなたには、いくつかのコンポーネントを理解する必要があるカスタムフィルタを作成するために、 。

デフォルトでは、スプリングはセキュリティ式を処理するために次のインターフェイスMethodSecurityExpressionHandlerを提供し、使用される実装はDefaultMethodSecurityExpressionHandlerです。通常、oauth2の場合はOAuth2MethodSecurityExpressionHandlerでオーバーライドしますが、独自の実装でカスタムのものを作成できます。

SecurityExpressionRootで実装されているインターフェイスMethodSecurityExpressionOperationsを使用して、式を解析します。

まず、カスタムMethodSecurityExpressionOperationsを作成する必要があります。それの一番下にあなたが(それは春の彼らの表情との互換性を保つために実装されているの上に)、カスタム・ロジックの開始を知らせる// custom logic methodsを見つけることができます。

public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations { 

    // Based on MethodSecurityExpressionRoot (class is package private in spring) 
    private Object filterObject; 
    private Object returnObject; 
    private Object target; 

    CustomMethodSecurityExpressionRoot(Authentication a) { 
     super(a); 
    } 

    public void setFilterObject(Object filterObject) { 
     this.filterObject = filterObject; 
    } 

    public Object getFilterObject() { 
     return filterObject; 
    } 

    public void setReturnObject(Object returnObject) { 
     this.returnObject = returnObject; 
    } 

    public Object getReturnObject() { 
     return returnObject; 
    } 

    /** 
    * Sets the "this" property for use in expressions. Typically this will be 
    * the "this" property of the {@code JoinPoint} representing the method 
    * invocation which is being protected. 
    * 
    * @param target 
    *   the target object on which the method in is being invoked. 
    */ 
    void setThis(Object target) { 
     this.target = target; 
    } 

    public Object getThis() { 
     return target; 
    } 

    // custom logic methods 
    public boolean securityHasPermission(String param, String anotherParam) { 
     /* custom logic here */ 
    } 

次に、我々は我々のルートとして設定する必要がありますカスタムMethodSecurityExpressionHandler

public class CustomOAuth2MethodSecurityExpressionHandler extends OAuth2MethodSecurityExpressionHandler { 

    private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); 

    @Override 
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, 
      MethodInvocation invocation) { 
     final CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication); 
     root.setThis(invocation.getThis()); 
     root.setPermissionEvaluator(getPermissionEvaluator()); 
     root.setTrustResolver(this.trustResolver); 
     root.setRoleHierarchy(getRoleHierarchy()); 

     return root; 
    } 

} 

次に、我々はデフォルトMethodSecurityExpressionHandlerとして設定する必要があります。 GlobalMethodSecurityConfigurationを拡張することでそれを実現できます。そのファイルに私たちは、カスタムMethodSecurityExpressionHandlerのための新しい@Beanを定義し、それをデフォルトとして設定するためにcreateExpressionHandler()をオーバーライド:

あなたのコントローラーで今
@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class Oauth2GlobalMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { 

    @Override 
    protected MethodSecurityExpressionHandler createExpressionHandler() { 
     return methodSecurityExpressionHandler(); 
    } 

    @Bean 
    public MethodSecurityExpressionHandler methodSecurityExpressionHandler() { 
     return new CustomOAuth2MethodSecurityExpressionHandler(); 
    } 

あなたは

カスタム・ロジック、カスタム・ロジックをトリガする@PreAuthorize("securityHasPermission('SOME', 'VALUE')")を追加することができますCustomMethodSecurityExpressionRootで起動され、authenticationにアクセスすることができます。これは、初期化時に既にクラスに注入されているためです。 CustomOAuth2MethodSecurityExpressionHandlerにそれを設定するときに、より多くのパラメータ/豆を渡すこともできます。

3

上記のコードには2つのことがあります。まず、クライアントにいくつかの権限を割り当てる必要があります。ここ

ことをやっていくつかのコード:

がOAuth2AuthorizationServerConfigに変更する必要があり、この

clients.inMemory().withClient("CLIENT_NAME").authorities("ADMIN")....; 

とマッチャーにあなたは

http.authorizeRequests().antMatchers(HttpMethod.GET, "/path/**") 
    .hasAuthority("ADMIN"); 

を行う必要がありますかあなたは安全な方法のために注釈を追加することができます/コントローラ

@PreAuthorize("hasAuthority('ADMIN')") 
0

これを解決するには、OAuth2MethodSecurityExpressionHandlerインスタンスをBeanとして生成します。

@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration { 

     @Override 
     protected MethodSecurityExpressionHandler createExpressionHandler() { 
      return new OAuth2MethodSecurityExpressionHandler(); 
     } 

     .... 
} 

は、次の操作を行います:

は、代わりにそれを行う、これは他の人をよ

@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration { 

     @Override 
     protected MethodSecurityExpressionHandler createExpressionHandler() { 
      return getOAuth2MethodSecurityExpressionHandler(); 
     } 

     @Bean 
     public OAuth2MethodSecurityExpressionHandler getOAuth2MethodSecurityExpressionHandler() { 
      return new OAuth2MethodSecurityExpressionHandler(); 
     } 

     .... 
} 

希望を!

関連する問題