복붙노트

[SPRING] 모든 역할 이름에 스프링 보안 접두사 "ROLE_"이 추가 되었습니까?

SPRING

모든 역할 이름에 스프링 보안 접두사 "ROLE_"이 추가 되었습니까?

Web Security Config에이 코드가 있습니다.

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/api/**")
            .hasRole("ADMIN")
            .and()
            .httpBasic().and().csrf().disable();

}

그래서 내 데이터베이스에 "ADMIN"역할을 가진 사용자를 추가했는데이 사용자와 함께 loggin을 tryed 할 때 항상 403 오류가 발생하고 봄용 로그가 활성화되었으며 다음 줄을 발견했습니다.

2015-10-18 23:13:24.112 DEBUG 4899 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /api/user/login; Attributes: [hasRole('ROLE_ADMIN')]

왜 Spring Security가 "ADMIN"대신 "ROLE_ADMIN"을 찾고 있습니까?

해결법

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

    1.스프링 보안은 기본적으로 접두사 "ROLE_"을 추가합니다.

    스프링 보안은 기본적으로 접두사 "ROLE_"을 추가합니다.

    제거하거나 변경하려는 경우 다음을 확인하십시오.

    http://forum.spring.io/forum/spring-projects/security/51066-how-to-change-role-from-interceptor-url

    수정 :이뿐만 아니라 발견 : 스프링 보안 제거 RoleVoter 접두어

  2. ==============================

    2.Spring 4에는 org.springframework.security.access.expression.SecurityExpressionRoot 클래스에 정의 된 hasAuthority ()와 hasAnyAuthority ()의 두 가지 메소드가있다. 이 두 메서드는 ROLE_ 접두어를 추가하지 않고 사용자 지정 역할 이름 만 검사합니다. 다음과 같은 정의 :

    Spring 4에는 org.springframework.security.access.expression.SecurityExpressionRoot 클래스에 정의 된 hasAuthority ()와 hasAnyAuthority ()의 두 가지 메소드가있다. 이 두 메서드는 ROLE_ 접두어를 추가하지 않고 사용자 지정 역할 이름 만 검사합니다. 다음과 같은 정의 :

    public final boolean hasAuthority(String authority) {
        return hasAnyAuthority(authority);
    }
    public final boolean hasAnyAuthority(String... authorities) {
        return hasAnyAuthorityName(null, authorities);
    }
    private boolean hasAnyAuthorityName(String prefix, String... roles) {
        Set<String> roleSet = getAuthoritySet();
    
        for (String role : roles) {
            String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
            if (roleSet.contains(defaultedRole)) {
                return true;
            }
        }
    
        return false;
    }
    private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
        if (role == null) {
            return role;
        }
        if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
            return role;
        }
        if (role.startsWith(defaultRolePrefix)) {
            return role;
        }
        return defaultRolePrefix + role;
    }
    

    사용 예 :

  3. ==============================

    3.@olyanren 슬픈 것처럼 hasRole () 대신 Spring 4에서 hasAuthority () 메소드를 사용할 수있다. JavaConfig 예제를 추가하고 있습니다.

    @olyanren 슬픈 것처럼 hasRole () 대신 Spring 4에서 hasAuthority () 메소드를 사용할 수있다. JavaConfig 예제를 추가하고 있습니다.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        .authorizeRequests()
        .antMatchers("/api/**")
        .access("hasAuthority('ADMIN')")
        .and()
        .httpBasic().and().csrf().disable();
    }
    
  4. ==============================

    4.모든 역할의 시작 부분에 _ROLE을 추가하는 매퍼를 만들 수 있습니다.

    모든 역할의 시작 부분에 _ROLE을 추가하는 매퍼를 만들 수 있습니다.

    @Bean
    public GrantedAuthoritiesMapper authoritiesMapper() {
        SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
        mapper.setPrefix("ROLE_"); // this line is not required 
        mapper.setConvertToUpperCase(true); // convert your roles to uppercase
        mapper.setDefaultAuthority("USER"); // set a default role
    
        return mapper;
    }
    

    공급자에게 매퍼를 추가해야합니다.

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        // your config ...
        provider.setAuthoritiesMapper(authoritiesMapper());
    
        return provider;
    }
    
  5. from https://stackoverflow.com/questions/33205236/spring-security-added-prefix-role-to-all-roles-name by cc-by-sa and MIT license