복붙노트

[SPRING] JavaConfig로 스프링 보안에서 ROLE_ 접두사를 어떻게 제거합니까?

SPRING

JavaConfig로 스프링 보안에서 ROLE_ 접두사를 어떻게 제거합니까?

스프링 보안에서 "ROLE_"접두어를 제거하려고합니다. 내가 처음 시도한 것은 :

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

그게 작동하지 않았으므로 http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4에서 제안 된대로 BeanPostProcessor를 만들려고했습니다. -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 check에서 ROLE_ 접두어를 제거 할 수 있습니까?

해결법

  1. ==============================

    1.Spring 4.2부터는 다음과 같이 단일 빈으로 접두어를 정의 할 수 있습니다 : https://github.com/spring-projects/spring-security/issues/4134

    Spring 4.2부터는 다음과 같이 단일 빈으로 접두어를 정의 할 수 있습니다 : 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>
    
  2. ==============================

    2.다음 구성이 저에게 효과적입니다.

    다음 구성이 저에게 효과적입니다.

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

    3.4.2 이전에 소위 유권자 (@hasRole 등의 주석을 사용하는 경우)를 사용하는 경우 문맥에서 다음과 같은 빈을 정의해야합니다.

    4.2 이전에 소위 유권자 (@hasRole 등의 주석을 사용하는 경우)를 사용하는 경우 문맥에서 다음과 같은 빈을 정의해야합니다.

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

    이 빈은 맞춤법 표현식에 대한 평가 컨텍스트를 만드는 데 사용되며 defaultRolePrefix는 'ROLE_'로 설정됩니다. 유스 케이스에 따라 다르지만. 이 작품은 저에게 이상적이었습니다.

    편집 : XML 구성에 대한 질문에 대답 - 물론 XML로 할 수 있습니다. 자바 구성에서 수행되는 모든 작업은 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. ==============================

    4.새 GrantedAuthorityDefaults가 DefaultWebSecurityExpressionHandler 및 DefaultMethodSecurityExpressionHandler의 접두어를 변경하지만 @EnableGlobalMethodSecurity에서 설정된 RoleVoter.rolePrefix는 수정하지 않는 것으로 보입니다.

    새 GrantedAuthorityDefaults가 DefaultWebSecurityExpressionHandler 및 DefaultMethodSecurityExpressionHandler의 접두어를 변경하지만 @EnableGlobalMethodSecurity에서 설정된 RoleVoter.rolePrefix는 수정하지 않는 것으로 보입니다.

    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;
        }
    }
    
  5. from https://stackoverflow.com/questions/38134121/how-do-i-remove-the-role-prefix-from-spring-security-with-javaconfig by cc-by-sa and MIT license