2013-11-22 88 views
0

我需要一些幫助。 你能告訴我我的Spring Security項目有什麼問題嗎? 這裏是我的的web.xml:Spring Security登錄在身份驗證後無法導航

 <display-name>Spring Project</display-name> 

     <welcome-file-list> 
       <welcome-file>login.xhtml</welcome-file> 
     </welcome-file-list> 


     <context-param> 
       <param-name>contextConfigLocation</param-name> 
       <param-value>/WEB-INF/applicationContext.xml</param-value> 
     </context-param> 

     <context-param> 
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name> 
       <param-value>.xhtml</param-value> 
     </context-param> 


     <listener> 
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
     </listener> 

     <servlet> 
       <servlet-name>Resources Servlet</servlet-name> 
       <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class> 
       <load-on-startup>0</load-on-startup> 
     </servlet> 

     <servlet-mapping> 
       <servlet-name>Resources Servlet</servlet-name> 
       <url-pattern>/resources/*</url-pattern> 
     </servlet-mapping> 

     <servlet> 
       <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> 
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
       <init-param> 
         <param-name>contextConfigLocation</param-name> 
         <param-value></param-value> 
       </init-param> 
       <load-on-startup>1</load-on-startup> 
     </servlet> 

     <servlet-mapping> 
       <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> 
       <url-pattern>/app/*</url-pattern> 
     </servlet-mapping> 

     <servlet> 
       <servlet-name>Faces Servlet</servlet-name> 
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
       <load-on-startup>1</load-on-startup> 
     </servlet> 

     <servlet-mapping> 
       <servlet-name>Faces Servlet</servlet-name> 
       <url-pattern>*.xhtml</url-pattern> 
     </servlet-mapping> 

     <filter> 
       <filter-name>charEncodingFilter</filter-name> 
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
       <init-param> 
      <param-name>encoding</param-name> 
      <param-value>UTF-8</param-value> 
     </init-param> 
     <init-param> 
      <param-name>forceEncoding</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     </filter> 

    <filter-mapping> 
     <filter-name>charEncodingFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <!-- Spring security filters --> 

    <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> 
       <dispatcher>REQUEST</dispatcher> 
       <dispatcher>FORWARD</dispatcher> 
     </filter-mapping> 

</web-app> 

安全-config.xml中

<security:http auto-config="true"> 
      <security:form-login login-page="/login.xhtml" authentication-failure-url="/loginfailed.xhtml" default-target-url="/succes.xhtml" /> 
      <security:logout logout-url="/app/logout" logout-success-url="/app/main" /> 
    </security:http> 


     <security:authentication-manager> 
       <security:authentication-provider user-service-ref="userService"> 
         <security:password-encoder hash="md5" /> 
       </security:authentication-provider> 
     </security:authentication-manager> 


    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
       <property name="userDetailsService" ref="userService" /> 
       <property name="hideUserNotFoundExceptions" value="false" /> 
    </bean> 

     <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager"> 
       <constructor-arg> 
         <ref local="daoAuthenticationProvider" /> 
       </constructor-arg> 
    </bean> 

</beans> 

這是我的登錄頁面。

<?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
       xmlns:ui="http://java.sun.com/jsf/facelets" 
       xmlns:h="http://java.sun.com/jsf/html" 
       xmlns:f="http://java.sun.com/jsf/core" 
       xmlns:p="http://primefaces.org/ui" 
       template="/WEB-INF/templates/general.xhtml"> 

     <ui:define name="title"><h:outputText value="Please Sign In" /></ui:define> 
     <ui:define name="header"><h:outputText value="Please Sign In" /></ui:define> 


     <ui:define name="content"> 
      <h:form id="loginForm" prependId="false"> 
        <p:fieldset styleClass="fieldset" legend="Authentication Form"> 
          <p:focus /> 
          <p:messages id="messages" /> 

          <h:panelGrid id="logPanelGrid" style="margin: 0 auto; margin-top: 25px; text-align: right" cellspacing="8" columns="3"> 
             <h:panelGroup> 
               <h:outputText value="User Name:" /> 
               <h:outputText style="color:red" value="* " /> 
             </h:panelGroup> 
             <p:inputText id="userName" value="#{userManagedBean.userName}" required="true" label="User Name" title="Enter your User Name!" /> 
             <h:panelGroup> 
               <p:message id="userNameMsg" for="userName" /> 
               <p:tooltip for="userName" styleClass="tooltip" showEvent="focus" hideEvent="blur" /> 
             </h:panelGroup> 

             <h:panelGroup> 
               <h:outputText value="Enter Password:" /> 
               <h:outputText style="color:red" value="* " /> 
             </h:panelGroup> 
             <p:password id="pass" value="#{userManagedBean.password}" required="true" label="Password" title="Please enter a password!" /> 
             <h:panelGroup> 
               <p:message id="passMsg" for="pass" /> 
               <p:tooltip for="pass" styleClass="tooltip" showEvent="focus" hideEvent="blur" /> 
             </h:panelGroup> 



            <p:commandButton id="submitButton" update="logPanelGrid,messages" action="#{userManagedBean.doLogin()}" value="SignIn" /> 

          </h:panelGrid> 
        </p:fieldset> 
      </h:form> 
     </ui:define> 

</ui:composition>  

對於器具認證我創建UserManagedbean與doLogin()方法。

package com.app.managed; 

    import javax.faces.bean.ViewScoped; 
    import javax.inject.Inject; 

    import org.springframework.stereotype.Component; 

    import com.app.model.UserEntity; 
    import com.app.service.UserService; 

    @Component 
    @ViewScoped 
    public class UserManagedBean { 

    public UserManagedBean(){ 
     System.out.println("Just for test, usermanagedbean nstantiated"); 
    } 
    @Inject 
    private UserService userService; 

    @Inject 
    private UserAuthenticationProviderServiceImpl userAuth; 

    private UserEntity user; 

    String userName; 
    String password; 


    public UserEntity getUser() { 
     return user; 
    } 

    public void setUser(UserEntity user) { 
     this.user = user; 
    } 

    public String getUserName() { 
     return userName; 
    } 

    public void setUserName(String userName) { 
     this.userName = userName; 
    } 

    public String getPassword() { 
     return password; 
    } 

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

    public boolean doLogin() { 
     UserEntity user = userService.loadUserEntityByUsername(userName); 
     return userAuth.processUserAuthentication(user); 
    } 



    } 

也是我創建UserAuthenticationProviderService

package com.app.managed; 

import javax.faces.application.FacesMessage; 
import javax.faces.context.FacesContext; 

import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.core.context.SecurityContextHolder; 
import org.springframework.stereotype.Service; 

import com.app.model.UserEntity; 


/** 
* Provides processing service to set user authentication session 
* 
* @author Arthur Vin 
*/ 
@Service("userAuthenticationProviderServiceImpl") 
public class UserAuthenticationProviderServiceImpl implements UserAuthenticationProviderService { 

     private AuthenticationManager authenticationManager; 

     /** 
     * Process user authentication 
     * 
     * @param user 
     * @return 
     */ 
     public boolean processUserAuthentication(UserEntity user) { 

       try { 
         System.out.println("11111"); 
         Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword()); 
         System.out.println("user.getUserName(), user.getPassword()" + user.getUserName() + " " + user.getPassword()); 

        Authentication result = authenticationManager.authenticate(request); 
        SecurityContextHolder.getContext().setAuthentication(result); 

        return true; 
      } catch(AuthenticationException e) { 
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Sorry!")); 

        return false; 
      } 
    } 

    public AuthenticationManager getAuthenticationManager() { 
      return authenticationManager; 
    } 

    public void setAuthenticationManager(AuthenticationManager authenticationManager) { 
      this.authenticationManager = authenticationManager; 
    } 

} 

並實現UserDeatailsS​​ervice

package com.app.service; 

    import java.util.ArrayList; 
    import java.util.Collection; 
    import java.util.ResourceBundle; 

    import javax.faces.application.FacesMessage; 
    import javax.faces.context.FacesContext; 
    import javax.faces.event.AjaxBehaviorEvent; 

    import org.primefaces.component.inputtext.InputText; 
    import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.security.core.GrantedAuthority; 
    import org.springframework.security.core.authority.SimpleGrantedAuthority; 
    import org.springframework.security.core.userdetails.User; 
    import org.springframework.security.core.userdetails.UserDetails; 
    import org.springframework.security.core.userdetails.UserDetailsService; 
    import org.springframework.security.core.userdetails.UsernameNotFoundException; 
    import org.springframework.stereotype.Service; 

    import com.app.dao.UserDao; 
    import com.app.model.UserEntity; 
    import com.app.service.intf.UserServiceIntf; 


    /** 
    * Service providing service methods to work with user data and entity. 
    * 
    * @author Arthur Vin 
    */ 
    @Service("userService") 
    public class UserService implements UserServiceIntf, UserDetailsService { 
      @Autowired 
      private UserDao userDao; 

     /** 
     * Check user name availability. UI ajax use. 
     * 
     * @param ajax event 
     * @return 
     */ 
     public boolean checkAvailable(AjaxBehaviorEvent event) { 

       InputText inputText = (InputText) event.getSource(); 
       String value = (String) inputText.getValue(); 

       boolean available = userDao.checkAvailable(value); 

       if (!available) { 
         FacesMessage message = constructErrorMessage(null, String.format(getMessageBundle().getString("userExistsMsg"), value)); 
         getFacesContext().addMessage(event.getComponent().getClientId(), message); 
       } else { 
         FacesMessage message = constructInfoMessage(null, String.format(getMessageBundle().getString("userAvailableMsg"), value)); 
         getFacesContext().addMessage(event.getComponent().getClientId(), message); 
       } 

       return available; 
     } 

     /** 
     * Construct UserDetails instance required by spring security 
     */ 
     public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { 

       UserEntity user = userDao.loadUserByUserName(userName); 

       if (user == null) { 
        System.out.println("NUL11!!"); 
         throw new UsernameNotFoundException(String.format(getMessageBundle().getString("badCredentials"), userName)); 

       } 

       Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
       authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 
       System.out.println("user.getUserName()"+ user.getUserName()); 
       User userDetails = new User(user.getUserName(), user.getPassword(), authorities); 

       return userDetails; 
     } 

     /** 
     * Retrieves full User record from database by user name 
     * 
     * @param userName 
     * @return UserEntity 
     */ 
     public UserEntity loadUserEntityByUsername(String userName) { 
       return userDao.loadUserByUserName(userName); 
     } 

     protected FacesMessage constructErrorMessage(String message, String detail){ 
       return new FacesMessage(FacesMessage.SEVERITY_ERROR, message, detail); 
     } 

     protected FacesMessage constructInfoMessage(String message, String detail) { 
       return new FacesMessage(FacesMessage.SEVERITY_INFO, message, detail); 
     } 

     protected FacesMessage constructFatalMessage(String message, String detail) { 
       return new FacesMessage(FacesMessage.SEVERITY_FATAL, message, detail); 
     } 

     protected FacesContext getFacesContext() { 
       return FacesContext.getCurrentInstance(); 
     } 

     protected ResourceBundle getMessageBundle() { 
       return ResourceBundle.getBundle("message-labels"); 
     } 

     public UserDao getUserDao() { 
       return userDao; 
     } 

     public void setUserDao(UserDao userDao) { 
       this.userDao = userDao; 
     } 

    } 

我也有用戶名密碼列UserEntity類。 因此,然後我點擊SignIn按鈕上的login.xhtml頁面,使用正確的用戶名和密碼頁面重新加載,而沒有其他。 有人可以告訴我,我做錯了什麼?

回答

0

doLogin()方法打破你的p:commandButton爲action屬性的合同:

public boolean doLogin() { 
     UserEntity user = userService.loadUserEntityByUsername(userName); 
     return userAuth.processUserAuthentication(user); 
    } 

該方法返回一個boolean。如果您想瀏覽其他地方,它應該返回一個String

public String doLogin() { 
     UserEntity user = userService.loadUserEntityByUsername(userName); 
     boolean result = userAuth.processUserAuthentication(user); 

     if (result) { 
      return "path/To/Landing/Page"; 
     } 

      //result was false - handle login error condition 

      //keep the view scope bean alive and don't change the page 
      return null; 
    } 

action方法火災後,返回的String是路徑認爲,用戶應該在事後採取。在你的情況下,我懷疑這會根據認證的結果而有所不同,但目前你還沒有。

由於您的方法簽名,無論有沒有任何Spring Security的東西,您最終都會在開始的地方結束。

+0

也許你幫我,我想,然後我點擊提交按鈕,如果驗證返回true,顯示消息框,在我的模板我創建的div block.What我必須IF情況下,顯示在此消息?

Welcome, ${user.firstName} ${user.lastName} |
MeetJoeBlack

+0

和我有新的錯誤,然後我嘗試驗證正確的用戶,我得到NullpoinerException在UserAuthenticationProviderServiceImpl 身份驗證結果= authenticationManager.authenticate(請求); – MeetJoeBlack

+0

@MeetJoeBlack如果你想留在同一頁面,而不管登錄是真還是假,那麼在任何情況下都簡單地返回null。該頁面不會改變,並且同一個實例視圖作用域bean將保持活動狀態。要顯示true對話框,你可以使用RequestContext.getCurrentInstance()。execute(「yourDialogName.show()」);有條件地,以編程方式顯示您的對話框。 – 8bitjunkie