@Secured( "ADMIN")(XMLなし、Java config、Spring Boot)のみ)を使用してメソッドセキュリティアノテーションを設定しようとしていますが、ロール経由のアクセスは機能しません。
セキュリティ構成:
_@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
.....
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated().and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
.....
}
_
コントローラーのメソッドへのアクセスを制限したい:
_@RestController
@RequestMapping("/api/groups")
public class GroupController {
@Autowired
private GroupService groupService;
@Secured("ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}
}
_
URLによるアクセスの制限は機能しています。
_.antMatchers("/api/**").hasAuthority("ADMIN")
_
ロールで制限することを指定するのを忘れたのでしょうか?
PD:ルールにより、どのレイヤーで@PreAuthorize("hasRole('ADMIN')")
がコントローラーレイヤーまたはサービスレイヤーにある必要がありますか?
この問題は解決されました。
@EnableGlobalMethodSecurity(prePostEnabled = true)
を追加します
_@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
}
_
そして、コントローラーで@Secured("ADMIN")
を@PreAuthorize("hasRole('ADMIN')")
に変更しました
親切にこれを追加してください
@EnableGlobalMethodSecurity(securedEnabled = true)
この要素は、(要素に適切な属性を設定することにより)アプリケーションで注釈ベースのセキュリティを有効にし、@Secured
専用にアプリケーションコンテキスト全体に適用されるセキュリティポイントカット宣言をグループ化するためにも使用されます。したがって、コードは次のようになります
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..
コントローラのメソッドセキュリティが機能しない多くの理由があります。
第一に、Spring Securityマニュアルで例として引用されていないためです...冗談ですが、行きたくない場所でSpringツールを使用するのは難しいかもしれません。
さらに深刻なのは、すでに@Mudassarが言ったようにメソッドセキュリティを有効にすることです。マニュアルによれば:
任意の@EnableGlobalMethodSecurity
インスタンスで@Configuration
注釈を使用して、注釈ベースのセキュリティを有効にできます。たとえば、次の例では、Spring Securityの@Secured
注釈が有効になります。
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}
Mudassarの答えはここまで正しいことに注意してください。
ただし、メソッドセキュリティはAOPに基づいており、デフォルトではinterfacesでJDKプロキシを使用します。サービスクラスは通常、コントローラーとしてインターフェイスとして挿入されるため、すべての例でサービスレイヤーにメソッドセキュリティが適用されるのはこのためです。
もちろん、コントローラー層で使用できますが、
@Secured
アノテーション付きメソッドを実装している私が従おうとするルールは次のとおりです。
私はこのスレッドが非常に古いことを知っており、私の答えはこのスレッドのさまざまな人々による答えの一部を暗示しています。しかし、ここに落とし穴と答えのリストを組み合わせたリストがあります:
動作するKotlinの例の一部を次に示します。
@RestController
@RequestMapping("api/v1")
open class DiagnosticsController {
@Autowired
lateinit var systemDao : SystemDao
@RequestMapping("ping", method = arrayOf(RequestMethod.GET))
@Secured("ROLE_ADMIN")
open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ...
}
そして
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
よろしく
私は自分の決定を共有したいと思います。それが役に立つかもしれません。
使用済みspring mvc+ spring security、version 4.2.9.RELEASE
たとえば、@ Securedアノテーションが付いたメソッドを持つサービスがあります
@Secured("ACTION_USER_LIST_VIEW")
List<User> getUsersList();
しかし、GlobalMethodSecurityConfigurationにはinsideメソッドがあるため、機能しませんでした。
protected AccessDecisionManager accessDecisionManager()
new RoleVoter()
をデフォルトのrolePrefix = "ROLE_";
で初期化した(これにより、beanを使用してrolePrefixを設定することができなくなります)RoleVoter'ROLE_'で始まる値
この問題を解決するには、GlobalMethodSecurityConfigurationこのようにオーバーライドします
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
expressionAdvice.setExpressionHandler(getExpressionHandler());
decisionVoters.add(getRoleVoter());
decisionVoters.add(new AuthenticatedVoter());
return new AffirmativeBased(decisionVoters);
}
private RoleVoter getRoleVoter() {
RoleVoter e = new RoleVoter();
e.setRolePrefix("");
return e;
}
}
@secured(ADMIN)の代わりに@secured(ROLE_ADMIN)を使用する必要があります。ロール名の前に"ROLE _"と書く必要があります。以下の例では、Adminロールを持つユーザーのみがlist()メソッドにアクセスできることを確認しています。
@RestController
@RequestMapping("/api/groups")
public class GroupController {
@Autowired
private GroupService groupService;
@Secured("ROLE_ADMIN")
@RequestMapping
public List<Group> list() {
return groupService.findAll();
}
}
たぶん、AppSecurityConfigurationをWebMvcConfigと同じコンテキストに登録する必要があります(WebMvcConfigurerAdapterを拡張します)。
AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
mvcContext.register(WebMvcConfig.class, SecurityConfig.class);