我正在尝试使用 Spring 3.1.1 和带有 LDAP 身份验证的 spring 安全性开发一个应用程序。此外,对于前端,我将使用带有 PrimeFaces 的 JSF 2.0。
我已经像这样配置了我的 LDAP 服务器和导航规则:
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="permitAll"/>
<security:intercept-url pattern="/pages/**" access="hasRole('ROLE_ADMIN')"/>
<security:form-login login-page="/login.xhtml" default-target-url="/index.xhtml"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider ref = "authProvider"/>
</security:authentication-manager>
<bean id="authProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<constructor-arg value="xxx" />
<constructor-arg value="ldap://xxx:389"/>
<property name="userDetailsContextMapper" ref = "customUserContextMapper"></property>
</bean>
<bean id="customUserContextMapper" class="CustomUserDetailsMapper"></bean>
我编写了一个自定义 UserDetailsMapper,它扩展了 LdapUserDetailsMapper,因为我不确定登录完成后在哪里放置“处理程序”:
public class CustomUserDetailsMapper extends LdapUserDetailsMapper{
private static final String ROLE_NORMAL_USER = "Normal User";
private static final String ROLE_ADMIN = "Administrator";
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx,
String username, Collection<? extends GrantedAuthority> authority) {
UserDetails originalUser = super.mapUserFromContext( ctx, username, authority );
originalUser.getAuthorities();
Set<AndaAuthority> roles = EnumSet.noneOf(AndaAuthority.class);
roles.add(AndaAuthority.ROLE_ADMIN);
for (GrantedAuthority auth : authority) {
if (ROLE_NORMAL_USER.equalsIgnoreCase(auth.getAuthority())) {
roles.add(AndaAuthority.ROLE_USER);
} else if (ROLE_ADMIN.equalsIgnoreCase(auth.getAuthority())) {
roles.add(AndaAuthority.ROLE_ADMIN);
}
}
SecurityContextHolder.getContext().getAuthentication().getCredentials();
User newUser =
new User(
originalUser.getUsername(),
originalUser.getPassword() != null? originalUser.getPassword():"",
originalUser.isEnabled(),
originalUser.isAccountNonExpired(),
originalUser.isCredentialsNonExpired(),
originalUser.isAccountNonLocked(),
roles );
return newUser;
}
}
我有一个位于 WEB-INF 根目录中的 login.xhtml 页面,我将其设置为欢迎页面。这是我的 web.xml:
[..]
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>login.xhtml</welcome-file>
</welcome-file-list>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- Spring Context Configuration' s Path definition -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
[..]
<!-- Spring security related configs -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[..]
以下是登录表格:
<h:form action="j_spring_security_check" method="post">
<h:panelGrid columns="2">
<h:outputText value="Username" />
<h:inputText id="j_username" />
<h:outputText value="Password" />
<h:inputSecret id="j_password" />
</h:panelGrid>
<div class="submit">
<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
<span class="ui-button-text">Login</span>
</button>
</div>
我从这个问题中得到了登录页面的想法。我不确定如何设置动作,无论是它j_spring_security_check
还是../j_spring_security_check
. 我尝试了两者并且结果相同......
发生了什么: 当我在 Tomcat 中打开应用程序时,会显示登录页面。输入凭据后,我再次被重定向到 login.xhtml,只填写了用户名。等等......
当我在示例 Spring 安全 LDAP 集成应用程序中使用我的配置进行尝试时,登录部分正在工作。在那里,该mapUserFromContext
方法每次都被调用。现在,断点永远不会进入。
此外,在示例应用程序中 - user.password始终为空,权限列表始终为空。这正常吗?任何人都可以建议一种更好的方法来覆盖正常登录以了解哪里有问题吗?
示例应用程序正在运行,因为它可能是用 JSP 制作的,而我用 JSF 搞砸了一些东西......
我相信这是我的 JSF 问题,但不知道为什么。另外,您知道如何为这种情况实施更好的“登录成功处理程序”吗?
非常感谢