Spring Security с Webflow и JSF перенаправляет страницу входа без сообщения об ошибке

Я пытаюсь написать приложение с пружинной безопасностью для аутентификации в 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> 

И поток для этого

логин.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);
}

}

Определенный компонент как

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 без сообщений об ошибках. Устали пробовать пару методов решения, которые не дали желаемого результата. Любая помощь действительно приветствуется.


person Inayathulla    schedule 03.08.2013    source источник


Ответы (1)


Метку ошибки можно найти в переменной sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message, поэтому добавьте на свою страницу входа: ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}, и будет отображаться сообщение об ошибке.

person e.carletti    schedule 20.11.2014