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> 

为此的流程是

登录.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定义为

登录凭据.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;
}

}

弹簧配置为

应用程序上下文安全.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 回答