Spring Security JAAS Authentication Authorization Issue
在 Spring Security 中,我使用 DefaultJaasAuthenticationProvider 配置使用 linux 用户名/密码进行登录身份验证。
JpamLoginModule 用于身份验证。我通过身份验证成功,但我在授权(ROLE_USER,ROLE_ADMIN)中遇到问题,
我收到 HTTP 状态 403 - 访问被拒绝错误。
我在 spring-security.xml 中使用的以下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <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"> <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 代码
1 2 3 4 5 6 7 8 9 10 11 | 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"); } |
}
建议会很有帮助
基于:http://jpam.sourceforge.net/xref/net/sf/jpam/jaas/JpamLoginModule.html 和 https://github.com/spring-projects/spring-security/blob/master/核心/src/main/java/org/springframework/security/authentication/jaas/AbstractJaasAuthenticationProvider.java
看起来你需要扩展 JpamLoginModule 来改变提交的行为。需要在扩展的 JpamLoginModule 中为主题分配主体。然后 AbstractJaasAuthenticationProvider (DefaultJaasAuthenticationProvider) 将遍历这些主体并将它们发送给您的 authorityGranters (RoleGranter)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | </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"))); } } |
尝试返回"ADMIN"而不是"ROLE_ADMIN"。 Spring 自动添加"ROLE"。