web-dev-qa-db-ja.com

Spring securityはすべてのロール名にプレフィックス「ROLE_」を追加しましたか?

Web Security Configに次のコードがあります。

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

}

そのため、データベースに「ADMIN」ロールを持つユーザーを追加し、このユーザーでログインを試行すると常に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」を検索する理由

23
Gustavo Rozolin

Spring Securityでは、デフォルトで接頭辞「ROLE _」が追加されます。

これを削除または変更する場合は、

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

編集:これも見つけました: 春のセキュリティはRoleVoterプレフィックスを削除

17
jmcg

Spring 4には、_org.springframework.security.access.expression.SecurityExpressionRoot_クラスで定義されているhasAuthority()hasAnyAuthority()の2つのメソッドがあります。これら2つのメソッドは、カスタムロール名のみをチェックしますwithoutプレフィックス_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;
}
_

使用例:

_<http auto-config="false" use-expressions="true" pattern="/user/**"
      entry-point-ref="loginUrlAuthenticationEntryPoint">
    <!--If we use hasAnyAuthority, we can remove ROLE_ prefix-->
    <intercept-url pattern="/user/home/yoneticiler" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
    <intercept-url pattern="/user/home/addUser" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
    <intercept-url pattern="/user/home/addUserGroup" access="hasAuthority('FULL_ADMIN')"/>
    <intercept-url pattern="/user/home/deleteUserGroup" access="hasAuthority('FULL_ADMIN')"/>
    <intercept-url pattern="/user/home/**" access="hasAnyAuthority('FULL_ADMIN','ADMIN','EDITOR','NORMAL')"/>
    <access-denied-handler error-page="/403"/>
    <custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
    <logout logout-url="/user/logout"
            invalidate-session="true"
            logout-success-url="/user/index?logout"/>
    <!-- enable csrf protection -->
    <csrf/>
</http>   <beans:bean id="loginUrlAuthenticationEntryPoint"
            class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:constructor-arg value="/user"/>
</beans:bean>
_
16
olyanren

@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();
}
3
Svitlana Onish

すべてのロールの最初に_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;
}
1
Hamid Mohayeji