私はメソッドレベルでアクセスルールを定義しようとしていますが、それは今までのところ何も機能していません。
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ルールに固執することを考えていますが、なぜそれが私にとってうまくいかないのかを知る必要があります。
コントローラでPrePostアノテーションを使用する場合の一般的な問題は、SpringメソッドのセキュリティがSpring AOPに基づいていることです。これはデフォルトでJDKプロキシに実装されています。
つまり、インターフェイスとしてコントローラーレイヤーに挿入されたサービスレイヤーでは正常に機能しますが、コントローラーは一般にインターフェイスを実装しないため、コントローラーレイヤーでは無視されます。
以下は私の意見です。
WebSecurityConfigに@EnableGlobalMethodSecurity(prePostEnabled = true)
を追加する必要があります。
ここにあります: http://www.baeldung.com/spring-security-expressions-basic
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
私は同様の問題を抱えていて、次のことで解決しました:
1)メソッドをパブリックにする必要がありました(つまり、メソッドをhome()パブリックにします)
2)hasAuthorityの代わりにhasRoleを使用する必要があります
コントローラー層で動作させるため。構成クラスに@EnableAspectJAutoProxyを配置する必要がありました。例:
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "com.abc.fraud.ts.userservices.web.controller" })
public class WebConfig extends WebMvcConfigurerAdapter{
}
これを使用するには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);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)を(WebSecurityConfigurerAdapterを拡張する)の代わりにMvcConfigクラスに追加する(WebMvcConfigurerAdapterを拡張する)。
以下の例のように:-
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MvcConfiguration extends WebMvcConfigurerAdapter {
セキュリティBeanのxmlコンテキストファイルとweb/servletコンテキストの別のxmlコンテキストファイルがある場合は、以下を追加する必要があります。
<security:global-method-security pre-post-annotations="enabled"/>
web-context.xml /サーブレットコンテキストに。セキュリティコンテキストxmlに追加するだけでは不十分です。
子コンテキストでは継承されません。
HTH