web-dev-qa-db-ja.com

JavaConfigを使用してSpring SecurityからROLE_プレフィックスを削除するにはどうすればよいですか?

Spring Securityの「ROLE_」プレフィックスを削除しようとしています。私が試した最初のことは:

http.servletApi().rolePrefix("");

それはうまくいかなかったので、 http://docs.spring.io/spring-security/site/migrate/current/3-to-4/で提案されているようにBeanPostProcessorを作成してみましたhtml5/migrate-3-to-4-jc.html#m3to4-role-prefixing-disable 。それもうまくいきませんでした。

最後に、自分のSecurityExpressionHandlerを作成してみました。

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          .authorizeRequests()
          .expressionHandler(webExpressionHandler())
          .antMatchers("/restricted").fullyAuthenticated()
          .antMatchers("/foo").hasRole("mycustomrolename")
          .antMatchers("/**").permitAll();
  }

  private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
      DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
      defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
      return defaultWebSecurityExpressionHandler;
  }

ただし、これも機能しません。 hasRoleの代わりに "hasAuthority(roleName)"を使用すると、期待どおりに動作します。

Spring SecurityのhasRoleチェックからROLE_プレフィックスを削除することは可能ですか?

13
Matt Raible

Spring 4.2以降、ここで説明するように、プレフィックスを単一のBeanで定義できます。 https://github.com/spring-projects/spring-security/issues/4134

@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}

XMLバージョン:

<beans:bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
    <beans:constructor-arg value="" />
</beans:bean>
19
Antoine Melki

次の設定は私にとってはうまくいきます。

@Override
public void configure(WebSecurity web) throws Exception {
    web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
        @Override
        protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
            WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
            root.setDefaultRolePrefix(""); //remove the prefix ROLE_
            return root;
        }
    });
}
7
walsh

4.2より前で、いわゆる有権者を使用している場合(@hasRoleなどのアノテーションを使用している場合)、コンテキストで以下のBeanを定義する必要があります。

@Bean
public DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
    DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
    defaultMethodSecurityExpressionHandler.setDefaultRolePrefix("");
    return defaultMethodSecurityExpressionHandler;
}

@Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
    defaultWebSecurityExpressionHandler.setDefaultRolePrefix("");
    return defaultWebSecurityExpressionHandler;
}

これらのBeanは、スペル式の評価コンテキストを作成するために使用され、defaultRolePrefixが 'ROLE_'に設定されています。ユースケースにもよりますが。これは私にとっては上手くいき、上手くいかなかった。

編集:xml構成に関する質問への回答->もちろんxmlで行うことができます。 Java configで行われたすべてのことはxml構成で記述できます。ここに例があります(ただし、テストしていないため、タイプミスか何かがある可能性があります):

<bean id="defaultWebSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
        <property name="defaultRolePrefix" value=""></property>
</bean>

<bean id="defaultMethodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="defaultRolePrefix" value=""></property>
</bean>
4
Piotr Tempes

新しいGrantedAuthorityDefaultsDefaultWebSecurityExpressionHandlerDefaultMethodSecurityExpressionHandlerの接頭辞を変更するようですが、RoleVoter.rolePrefixから設定された@EnableGlobalMethodSecurityは変更しません。

RoleVoter.rolePrefixは、@Secured("ADMIN")スタイルのメソッドセキュリティに使用されるものです。

したがって、GrantedAuthorityDefaultsとともに、このCustomGlobalMethodSecurityクラスを追加して、RoleVoterのデフォルトをオーバーライドする必要がありました。

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class CustomGlobalMethodSecurity extends GlobalMethodSecurityConfiguration {

    protected AccessDecisionManager accessDecisionManager() {
        AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();

        //Remove the ROLE_ prefix from RoleVoter for @Secured and hasRole checks on methods
        accessDecisionManager.getDecisionVoters().stream()
                .filter(RoleVoter.class::isInstance)
                .map(RoleVoter.class::cast)
                .forEach(it -> it.setRolePrefix(""));

        return accessDecisionManager;
    }
}
3
Jeff Sheets

Spring Boot 2を使用する場合、このBeanを作成してRoteVoterプレフィックスをオーバーライドできます。

@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return  new GrantedAuthorityDefaults("<anything you want>");
}

GlobalMethodSecurityConfigurationAccessDecisionManagerをメソッドGlobalMethodSecurityConfiguration.accessDecisionManager()に作成すると、これが機能します。これがコードのスニペットです。grantedAuthorityDefaultsのnullチェックに注意してください。

    protected AccessDecisionManager accessDecisionManager() {
    ....
    RoleVoter roleVoter = new RoleVoter();
    GrantedAuthorityDefaults grantedAuthorityDefaults =
            getSingleBeanOrNull(GrantedAuthorityDefaults.class);
    if (grantedAuthorityDefaults != null) {
        roleVoter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
    }
    decisionVoters.add(roleVoter);
    decisionVoters.add(new AuthenticatedVoter());
    return new AffirmativeBased(decisionVoters);
}
0
Hung Tran

私は作業ソリューションの概要を投稿します。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    /**
     * Allow skip ROLE_ when check permission using @Secured, like:
     *  @Secured({AuthorityConstants.ROLE_SYSTEM_ADMIN})
     */
    @Override
    protected AccessDecisionManager accessDecisionManager() {
        AffirmativeBased accessDecisionManager = (AffirmativeBased) super.accessDecisionManager();
        setAuthorityRolePrefix(accessDecisionManager, "");
        return accessDecisionManager;
    }

    private void setAuthorityRolePrefix(AffirmativeBased accessDecisionManager, String rolePrefix) {
        accessDecisionManager.getDecisionVoters().stream()
                .filter(RoleVoter.class::isInstance)
                .map(RoleVoter.class::cast)
                .forEach(it -> it.setRolePrefix(rolePrefix));
    }

    /**
     * Allow skip ROLE_ when check permission using @PreAuthorize, like:
     * @PreAuthorize("hasAnyRole('USER', 'SYSTEM_ADMIN')")
     */
    @Bean
    GrantedAuthorityDefaults grantedAuthorityDefaults() {
        return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
    }
}
0
chi nguyen