2

Spring 3.1.1 を使用して、Spring Security と LDAP 認証を使用してアプリを開発しようとしています。また、フロントエンドには JSF 2.0 と PrimeFaces を使用します。

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>

ログインが完了した後に「ハンドラー」を配置する場所が他にわからないため、LdapUserDetailsMapper を拡張するカスタム UserDetailsMapper を作成しました。

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は常にnullで、権限リストは常に空でした。それは正常ですか?何かが壊れている場所を知るために、通常のログインをオーバーライドするより良い方法を提案できますか?

サンプルアプリはJSPで作ったので動いていたのかもしれませんが、JSFで何かを台無しにしました...

これは私の側の JSF の問題だと思いますが、その理由がわかりません。また、この場合により良い「ログイン成功ハンドラー」を実装する方法はありますか?

どうもありがとう

4

0 に答える 0