【问题标题】:Spring Security JAAS Authentication Authorization IssueSpring Security JAAS 身份验证授权问题
【发布时间】:2014-05-11 18:32:47
【问题描述】:

在 Spring Security 中,我使用 DefaultJaasAuthenticationProvider 配置使用 linux 用户名/密码进行登录身份验证。 JpamLoginModule 用于身份验证。我通过身份验证成功,但我在授权(ROLE_USER,ROLE_ADMIN)中遇到问题, 收到 HTTP 状态 403 - 访问被拒绝错误。

我在 spring-security.xml 中使用的以下配置

<security:authentication-manager>
    <security:authentication-provider ref="jaasAuthProvider" />
</security:authentication-manager>

<bean id="jaasAuthProvider"  class="org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider">
    <property name="configuration">
        <bean class="org.springframework.security.authentication.jaas.memory.InMemoryConfiguration">
            <constructor-arg>
                <map>
                    <entry key="SPRINGSECURITY">
                        <array>
                            <bean class="javax.security.auth.login.AppConfigurationEntry">
                                <constructor-arg value="net.sf.jpam.jaas.JpamLoginModule" />
                                <constructor-arg>
                                    <util:constant  static-field="javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag.REQUIRED" />
                                </constructor-arg>
                                <constructor-arg>
                                    <map></map>
                                </constructor-arg>
                            </bean>
                        </array>
                    </entry>
                </map>
            </constructor-arg>
        </bean>
    </property>
    <property name="authorityGranters">
        <list>
            <bean class="it.webapps.pam.RoleGranter" />
        </list>
    </property>
</bean> 
    <bean id="userDetailsService" class="it.webapps.pam.UserDetailsServiceImpl">  
</bean> 

RoleGranter.java 代码

public class RoleGranter implements AuthorityGranter {

public RoleGranter() {
    System.out.print("=== Creating My Authority Granter ===");
 }

@Override
public Set<String> grant(Principal principal) {

        return Collections.singleton("ROLE_ADMIN");
}

}

建议会很有帮助

【问题讨论】:

    标签: java spring spring-security jaas


    【解决方案1】:

    基于:http://jpam.sourceforge.net/xref/net/sf/jpam/jaas/JpamLoginModule.htmlhttps://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/jaas/AbstractJaasAuthenticationProvider.java

    看起来您需要扩展 JpamLoginModule 以更改提交的行为。需要在扩展的 JpamLoginModule 中为主题分配主体。然后 AbstractJaasAuthenticationProvider (DefaultJaasAuthenticationProvider) 将遍历这些主体并将它们发送给您的 authorityGranters (RoleGranter)。

    <authentication-manager>
        <authentication-provider ref="jaasAuthProvider" />
    </authentication-manager>
    
    <beans:bean id="userService" class="blah.UserDetailsServiceImpl" />  
    
    <beans:bean id="jaasAuthProvider"  class="org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider">
        <beans:property name="configuration">
            <beans:bean class="org.springframework.security.authentication.jaas.memory.InMemoryConfiguration">
                <beans:constructor-arg>
                    <beans:map>
                        <beans:entry key="SPRINGSECURITY">
                            <beans:array>
                                <beans:bean class="javax.security.auth.login.AppConfigurationEntry">
                                    <beans:constructor-arg value="blah.RoleGrantingJpamLoginModule" />
                                    <beans:constructor-arg>
                                        <util:constant  static-field="javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag.REQUIRED" />
                                    </beans:constructor-arg>
                                    <beans:constructor-arg>
                                        <beans:map></beans:map>
                                    </beans:constructor-arg>
                                </beans:bean>
                            </beans:array>
                        </beans:entry>
                    </beans:map>
                </beans:constructor-arg>
            </beans:bean>
        </beans:property>
        <beans:property name="authorityGranters">
            <beans:list>
                <beans:bean class="blah.RoleGranter" />
            </beans:list>
        </beans:property>
    </beans:bean> 
    
    package blah;
    
    import javax.security.auth.Subject;
    import javax.security.auth.login.LoginException;
    
    import net.sf.jpam.jaas.JpamLoginModule;
    
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    
    public class RoleGrantingJpamLoginModule extends JpamLoginModule {
        private Subject subject;
    
        @Override
        public void initialize(javax.security.auth.Subject subject, javax.security.auth.callback.CallbackHandler callbackHandler, java.util.Map sharedState, java.util.Map options) {
            super.initialize(subject, callbackHandler, sharedState, options);
            this.subject = subject;
        }
    
        @Override
        public boolean commit() throws LoginException {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null);
            subject.getPrincipals().add(token);
            return super.commit();
        }
    }
    
    
    package blah;
    
    import static java.util.Arrays.asList;
    
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    
    public class UserDetailsServiceImpl implements UserDetailsService {
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            return new User(username, "password", asList(new SimpleGrantedAuthority("ROLE_ADMIN")));
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      尝试返回“ADMIN”而不是“ROLE_ADMIN”。 Spring 自动添加“ROLE”。

      【讨论】:

      • 我也试过这个“return Collections.singleton("ADMIN")”,但是 HTTP 状态 403 - 访问被拒绝。我正在使用 spring-security-core-3.1.0.RC3 jar。还有其他调试方法吗?
      猜你喜欢
      • 2010-11-22
      • 2011-07-17
      • 1970-01-01
      • 2015-10-12
      • 2019-04-08
      • 2016-08-15
      • 1970-01-01
      • 2016-05-29
      • 2021-02-24
      相关资源
      最近更新 更多