web-dev-qa-db-ja.com

事前認証がコントローラーで機能しない

私はメソッドレベルでアクセスルールを定義しようとしていますが、それは今までのところ何も機能していません。

SecurityConfiguration

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().
                withUser("user").password("user").roles("USER").and().
                withUser("admin").password("admin").roles("ADMIN");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/v2/**").authenticated()
                .and()
                .httpBasic()
                .realmName("Secure api")
                .and()
                .csrf()
                .disable();
    }
}

ExampleController

@EnableAutoConfiguration
@RestController
@RequestMapping({"/v2/"})
public class ExampleController {
    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    @RequestMapping(value = "/home", method = RequestMethod.GET)
    String home() {
        return "Hello World";
    }
}

user:userを使用して/ v2/homeにアクセスしようとすると、正常に実行されますが、「ユーザー」にROLE_ADMINがないため、アクセス拒否エラーが表示されませんか?

私は実際にメソッドレベルでアクセスルールを捨て、http()antルールに固執することを考えていますが、なぜそれが私にとってうまくいかないのかを知る必要があります。

21
prettyvoid

コントローラでPrePostアノテーションを使用する場合の一般的な問題は、SpringメソッドのセキュリティがSpring AOPに基づいていることです。これはデフォルトでJDKプロキシに実装されています。

つまり、インターフェイスとしてコントローラーレイヤーに挿入されたサービスレイヤーでは正常に機能しますが、コントローラーは一般にインターフェイスを実装しないため、コントローラーレイヤーでは無視されます。

以下は私の意見です。

  • 望ましい方法:サービスレイヤーでポストポストアノテーションを移動する
  • できない(またはしたくない)場合は、すべての注釈付きメソッドを含むインターフェイスをコントローラーに実装してください
  • 最後の方法として、proxy-target-class = trueを使用します
24
Serge Ballesta

WebSecurityConfigに@EnableGlobalMethodSecurity(prePostEnabled = true)を追加する必要があります。

ここにあります: http://www.baeldung.com/spring-security-expressions-basic

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
22
Eric Zürcher

私は同様の問題を抱えていて、次のことで解決しました:

1)メソッドをパブリックにする必要がありました(つまり、メソッドをhome()パブリックにします)

2)hasAuthorityの代わりにhasRoleを使用する必要があります

7
Horowitzathome

コントローラー層で動作させるため。構成クラスに@EnableAspectJAutoProxyを配置する必要がありました。例:

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "com.abc.fraud.ts.userservices.web.controller" })
public class WebConfig extends WebMvcConfigurerAdapter{

}
2
kripal kashyav

これを使用するには2つの異なる方法があります。1つはプレフィックスを使用する方法、もう1つは使用しない方法です。そして、おそらく@PreAuthorize("hasAuthority('ROLE_ADMIN')")@PreAuthorize("hasAuthority('ADMIN')")に変更しても大丈夫です。

次は@PreAuthorize ソースコード。

private String defaultRolePrefix = "ROLE_";
public final boolean hasAuthority(String authority) {
    return hasAnyAuthority(authority);
}

public final boolean hasAnyAuthority(String... authorities) {
    return hasAnyAuthorityName(null, authorities);
}

public final boolean hasRole(String role) {
    return hasAnyRole(role);
}

public final boolean hasAnyRole(String... roles) {
    return hasAnyAuthorityName(defaultRolePrefix, roles);
}
1
beautifulcode

@EnableGlobalMethodSecurity(prePostEnabled = true)を(WebSecurityConfigurerAdapterを拡張する)の代わりにMvcConfigクラスに追加する(WebMvcConfigurerAdapterを拡張する)。

以下の例のように:-

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MvcConfiguration extends WebMvcConfigurerAdapter {
0
stanicmail

セキュリティBeanのxmlコンテキストファイルとweb/servletコンテキストの別のxmlコンテキストファイルがある場合は、以下を追加する必要があります。

<security:global-method-security pre-post-annotations="enabled"/>

web-context.xml /サーブレットコンテキストに。セキュリティコンテキストxmlに追加するだけでは不十分です。

子コンテキストでは継承されません。

HTH

0
Chris