4

Spring Security OAuth2 kullanıyorum, gayet düzgün çalışan çok basit bir yapılandırmayla. Şimdi, bazı uç noktalara erişme yetkisinin olup olmadığını belirleyen özel mantığı içeren ayrı bir WebSecurityConfigurerAdapter olmasını istiyorum. Ancak ne denediğime bakılmaksızın yürütülür. Aşağıda benim OAuth2 yapılandırmalarım ve konuyla ilgili bulgularım var. Yetkilendirme sunucusu:OAuth2 kaynak sunucusuyla birlikte özel http güvenlik yapılandırması

@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")...; 
    } 

} 

Kaynak sunucusu: Şimdiye kadar

@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); 
    } 
} 

çok iyi. Özel WebSecurityConfigurerAdapter devreye girdiğinde, sorun yaşamaya başladım. EnableResourceServer eklenmiş fasulyenin, Order(3) ile bir WebSecurityConfigurerAdapter oluşturması nedeniyle, önce her istekte yürütülür, kullanıcı başarıyla doğrulanır/yetkilendirilir, ancak WebSecurityConfiguration benim özel mantığım yürütülür. Diğer yandan WebSecurityConfiguration değerini Order(2) veya daha düşük bir değere ayarlıyorumsa, özel access kuralları yerine getirilir, ancak her zaman anonim bir kullanıcıdan geldikleri söylenir (@EnableResourceServer tarafından oluşturulan fasulye kurallarının yerine getirilmediğinden). Sadece bir yan not olarak

@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 kurallarda @security referans sadece basit adlandırılmış Bahar fasulye geçerli:

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

ben WebSecurityConfiguration özel erişim kuralları doğrulamak entegrasyon testleri ve çalıştıkları (orada kimlik doğrulamasını atladığımdan). Kaynak sunucuyu yalnızca kimlik doğrulaması için kullanabiliyorum ve daha sonra yetkilendirmek için özel http güvenliğimi kullanmak istiyorum.

cevap

0

Oauth2'yi kullanmak istediğinizi varsayalım ve önce bir belirti alıp API'nızda kullanabilirsiniz (Authorization Bearer [TOKEN] kullanarak), özel ifadeler oluşturmak için mantığınızı biraz değiştirmeniz gerekir. Eğer bazı bileşenleri anlamak gerekir özel filtreler oluşturmak için security.oauth2.resource.filter-order=3 (1.5 release notes) Artık

: Eğer yay çizme 1.5+ kullanıyorsanız tüm

Öncelikle, sizin application.properties dosyasına aşağıdaki özelliğini eklemeyi düşünün lütfen .

Varsayılan olarak, güvenlik ifadelerini ele almak için MethodSecurityExpressionHandler numaralı aşağıdaki arabirimi sağlayın ve kullanılan uygulama DefaultMethodSecurityExpressionHandler'dir. Genellikle, oauth2 için OAuth2MethodSecurityExpressionHandler ile geçersiz kılabilirsiniz, ancak kendi uygulamanıza özel bir tane oluşturmanıza izin verir.

Bu sınıf, ifadeleri ayrıştırmak için SecurityExpressionRoot tarafından uygulanan MethodSecurityExpressionOperations arabirimini kullanır.

İlk olarak, özel bir MethodSecurityExpressionOperations oluşturmanız gerekir. Bunun altındaki misiniz (bahar onların ifadeleri ile uyumluluğu korumak için uygulama vardır üstünde) özel mantığı başlangıcını belirten // custom logic methods bulabilirsiniz:

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 */ 
    } 

Sonra, bizim root olarak ayarlamak gerekir özel bir 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; 
    } 

} 

sonra, varsayılan MethodSecurityExpressionHandler olarak ayarlamak gerekir. Bunu GlobalMethodSecurityConfiguration genişleterek yapabiliriz. Eğer özel mantık

Sizin özel mantık tetiklemek için @PreAuthorize("securityHasPermission('SOME', 'VALUE')") ekleyebilir

denetleyicileri Şimdi
@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class Oauth2GlobalMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { 

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

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

: bu dosyada biz varsayılan olarak ayarlayın amacıyla bizim özel MethodSecurityExpressionHandler ve öncelikli createExpressionHandler() için yeni @Bean tanımlamak CustomMethodSecurityExpressionRoot'da tetiklenmelidir ve authentication değişkenine, başlangıç ​​durumuna getirildikten sonra zaten enjekte edildiği için erişebilirsiniz. CustomOAuth2MethodSecurityExpressionHandler’a ayarlarken daha fazla parametre/fasulye de geçirebilirsiniz.

3

Yukarıdaki kodda iki şey vardır, önce istemciyi bazı yetkililere atamalısınız. Burada

yapıyor bazı kod:

OAuth2AuthorizationServerConfig Üzerinde değişiklik gerektiğini bu

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

ve Eşleştirici size

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

yapmalıyım yoksa güvenli yöntem için ek açıklama ekleyebilir/denetleyici

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

Bu sorunu, OAuth2MethodSecurityExpressionHandler örneğini çekirdek olarak çözebilirsiniz.

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

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

     .... 
} 

bunu:

yerine bunu bu diğerlerini olacak

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

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

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

     .... 
} 

Umut!