0

JSF と wedflow での認証のための春のセキュリティを備えたアプリケーションを作成しようとしています。

以下はコード スニペットです。

ログインページ.xhtml

<h:form id="form" class="lgnfrm">
    <div id="LoginSection">
        <fieldset class="LoginBorder">
            <legend class="signin">SIGN IN</legend>
            <div>
                <div class="UsernameIcon">
                    <h:inputText id="username" maxlength="100"
                        value="#{loginCredential.loginUserId}"
                        onfocus="this.value='';"
                        requiredMessage="Please enter a username" styleClass="Width100px LoginTextbox" />                   

                </div>
                <div class="PasswordIcon">
                    <h:inputSecret id="password" maxlength="100"
                        value="#{loginCredential.password}"
                        requiredMessage="Please enter a password"
                        onfocus="this.value='';" styleClass="Width100px LoginTextbox" />                    

                </div>
                <div class="FloatLeft">
                    <h:commandButton id="loginControl" value="SIGN IN"
                        styleClass="signinButton" action="verifyCredentials" />                     

                 </div>
                <h:panelGroup rendered="#{viewScope.isLoginError == 'true'}">  
                    <h:outputText value="#{msg['auth.failure']}" />
                    <h:outputText value="Invalid Credentials!!" />
                </h:panelGroup>                
                <div class="FloatRight ForgotPWD"></div>
            </div>
        </fieldset>
    </div>  
  </h:form> 

そして、その流れは

login.xml

<view-state id="loginViewState" view="loginPage">
    <on-entry>
        <evaluate           
            expression="new com.iri.rpm.web.ui.beans.authentication.LoginCredential()"
            result="viewScope.loginCredential" />
    </on-entry>

    <transition on="verifyCredentials" to="validateCredentials">
        <evaluate expression="authenticationService.challengeUser(loginCredential)"
            result="flowScope.auth" />
    </transition>

</view-state>

<decision-state id="validateCredentials">
    <if test="true" then="AgentViewState"
                else="invalidCredentialsState" />
</decision-state>

<end-state id="AgentViewState" view="flowRedirect:contract" />

<view-state id="invalidCredentialsState"  view="logout" >
    <on-entry>
        <evaluate           
            expression="new com.iri.rpm.web.ui.beans.authentication.LoginCredential()"
            result="viewScope.loginCredential" />
        <set name="viewScope.isLoginError" value="true" />  
    </on-entry>

    <transition on="verifyCredentials" to="validateCredentials">
        <evaluate expression="authenticationService.challengeUser(loginCredential)" result="flowScope.auth" />
    </transition>   
</view-state>

サービス層クラスとして

AuthenticationServiceImpl.java

package com.iri.rpm.web.ui.services;

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

import com.iri.rpm.web.ui.beans.authentication.LoginCredential; 

public class AuthenticationServiceImpl implements IAutheticationService {

@Autowired
private AuthenticationManager authenticationManager; 

@Override
public LoginCredential challengeUser(LoginCredential loginCredential) {
    Authentication authentication = createPreAuthenticatedAuthenticationToken(loginCredential.getLoginUserId());
    try {

        if ((loginCredential.getPassword() == null) ||  (loginCredential.getPassword() == "")) {

            // default it to something else;
            loginCredential.setPassword("xxxxx");
        }

        authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginCredential.getLoginUserId(), loginCredential.getPassword()));

        //authentication.setAuthenticated(true);
        loginCredential.setAuthenticated(true);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    } catch (BadCredentialsException bce) {
        bce.printStackTrace();
        loginCredential.setAuthenticated(false);
        handleBadCredentialsException(loginCredential.getLoginUserId());
    } catch (Exception e) {
        e.printStackTrace();
        loginCredential.setAuthenticated(false);
        handleSystemException(loginCredential.getLoginUserId());
    }

    return loginCredential;
}

/**
 * Handle system exception and re route the user to login page.
 * 
 * @param loginCredential
 */
private void handleSystemException(String loginCredential) {
    Authentication authentication = createPreAuthenticatedAuthenticationToken(loginCredential);
    authentication.setAuthenticated(false);
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

/**
 * Handle bad credential and re route the user to login page.
 * 
 * @param loginCredential
 */
private void handleBadCredentialsException(String loginCredential) {
    Authentication authentication = createPreAuthenticatedAuthenticationToken(loginCredential);
    authentication.setAuthenticated(false);
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

/**
 * Util method to create pre authentication token
 * 
 * @param loginCredential
 * @return
 */
private Authentication createPreAuthenticatedAuthenticationToken(
        String loginCredential) {

    return new PreAuthenticatedAuthenticationToken(loginCredential, "");
}

@Override
public void logoutAuth() {
    SecurityContextHolder.getContext().setAuthentication(null);
}

}

Bean を次のように定義

LoginCredential.java

package com.iri.rpm.web.ui.beans.authentication;

import java.io.Serializable;

public class LoginCredential  implements Serializable{

private static final long serialVersionUID = 1L;

private String loginUserId;

transient private String password;

private boolean authenticated;

public LoginCredential(){
       super();
}

public boolean isAuthenticated() {
    return authenticated; 
}

public void setAuthenticated(boolean authenticated) {
    this.authenticated = authenticated;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getLoginUserId() {
    return loginUserId;
}

public void setLoginUserId(String loginUserId) {
    this.loginUserId = loginUserId;
}

}

春の構成として

application-Context-security.xml

<security:http auto-config="true" use-expressions="true">
    <security:form-login login-page="/flow/login" default-target-url="/flow/login" authentication-failure-url="/flow/login?login_error=1" />

    <security:intercept-url pattern="/flow/login**" access="permitAll"/>
    <security:intercept-url pattern="/flow/javax.faces.resource/**" access="permitAll"/>    
    <security:intercept-url pattern="/**" access="isAuthenticated()" />


    <security:logout  logout-success-url="/logout.xhtml"  invalidate-session="true" />

    <security:intercept-url pattern="/secure" method="POST" access="hasRole('ROLE_SUPERVISOR')"/>
</security:http>



<security:authentication-manager erase-credentials="true" alias="authenticationManager">
    <security:authentication-provider ref="ldapActiveDirectoryAuthProvider"/>
</security:authentication-manager>  

<bean id="ldapActiveDirectoryAuthProvider" class="com.iri.rpm.web.security.RPMActiveDirectoryLdapAuthenticationProvider">
    <constructor-arg value="infores.com" />
    <constructor-arg value="ldap://170.118.24.149:389" />
    <property name="userDetailsContextMapper" ref="rpmUserDetailsContextMapper"/>
</bean>

<bean id="rpmUserDetailsContextMapper" class="com.iri.rpm.web.security.RPMUserDetailsContextMapper"/>

私が言わなければならないのは、認証が行われ、認証が完了したときに対応するフローに入るということです.資格情報がエラーメッセージなしで同じloginPage.xhtmlをスローすることに失敗した瞬間です。解決するためにいくつかの方法を試すのにうんざりしていましたが、それらは望ましい結果をもたらしませんでした。どんな助けも本当に感謝しています。

4

1 に答える 1

0

エラー ラベルは sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message 変数で見つけることができるので、ログイン ページに ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message} を追加すると、エラー メッセージが表示されます。

于 2014-11-20T10:24:17.220 に答える