Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 28

Thread: Can't get IceFaces login form to work

  1. #11
    Join Date
    Jun 2009
    Location
    Timisoara
    Posts
    15

    Default

    Can you please also post your login page and login bean?

    Dumi.

  2. #12
    Join Date
    Jul 2009
    Location
    Düsseldorf, Germany
    Posts
    15

    Default

    In the meantime I got a least a bit further. I had some misconfiguration in my Maven POM which is solved now. However I still have problems with Spring Security getting the message:

    Code:
    Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Authentication m
    ethod not supported: GET
    My login-Method looks like this:
    Code:
    	public void login(ActionEvent e) throws java.io.IOException {
    		FacesContext context = FacesContext.getCurrentInstance();
    		ExternalContext ec = context.getExternalContext();
    		String encodedURL = ec.encodeResourceURL(ec.getRequestContextPath() + "/j_spring_security_check?j_username=" + loginName.toLowerCase() + "&j_password=" + password + "&_spring_security_remember_me=" + "true");
    	
    		ec.redirect(encodedURL);
    
    		FacesContext.getCurrentInstance().responseComplete();
    
    	}
    My Login-Form is like this:
    Code:
    	<body>
    	<h2>Login</h2>
    	<ice:form>
    		<ice:panelGrid columns="3">
    
    			<ice:outputText value="Benutzername: " />
    			<ice:inputText id="j_username" value="#{LoginController.loginName}"
    				redisplay="true" />
    			<br />
    
    			<ice:outputText value="Passwort: " />
    			<ice:inputSecret id="j_password" value="#{LoginController.password}" />
    			<br />
    
    			<ice:commandButton actionListener="#{LoginController.login}" value="Login"/>
    
    		</ice:panelGrid>
    		<ice:messages style="color: red;"/>
    	</ice:form>
    	</body>
    It seems as Version 3 of Spring Security is not accepting GETs anymore (which I can understand). However I am wondering how to POST the credentials to the Spring Security Filter.

  3. #13
    Join Date
    Jun 2009
    Location
    Timisoara
    Posts
    15

    Default

    Yes, this is where I also got today using your configuration files. This "Authentication method not supported: GET" is caused by the latest version of Spring Security. In my projects I'm using Spring 2.5.6.SEC01 and Spring Security 2.0.4.
    What I was trying right now was to change the version of Spring/Spring Security in your pom to the ones that work for me, but I'm getting some other errors.
    I'll play more with it tomorrow. In the end I will also need to use Spring 3, so we must find a solution

    Dumi.

  4. #14
    Join Date
    Jul 2009
    Location
    Düsseldorf, Germany
    Posts
    15

    Default

    Just as an Update: What I have changed since yesterday is my POM. This was essential to have the right set of JARs:

    Code:
    	<properties>
    		<spring.version>3.0.2.RELEASE</spring.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>org.springframework.orm</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>org.springframework.asm</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>org.springframework.web</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.security</groupId>
    			<artifactId>org.springframework.security.web</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.security</groupId>
    			<artifactId>org.springframework.security.core</artifactId>
    			<version>${spring-security.version}</version>
    			<scope>compile</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.security</groupId>
    			<artifactId>org.springframework.security.config</artifactId>
    			<version>${spring-security.version}</version>
    			<scope>compile</scope>
    		</dependency>
    	</dependencies>

  5. #15
    Join Date
    Jun 2009
    Location
    Timisoara
    Posts
    15

    Default

    I've managed to make it work, but I'm not using j_spring_security_check anymore. Here is the updated code in my login bean:

    Code:
    public AuthenticationManager getAuthenticationManager() {
    	return authenticationManager;
    }
    
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
    	this.authenticationManager = authenticationManager;
    }
    
    public void login(ActionEvent e) throws IOException {
    	try {
    		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    		UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password);
    		authToken.setDetails(authentication.getDetails());
    
    		FacesContext context = FacesContext.getCurrentInstance();
    		ExternalContext ec = context.getExternalContext();
    		((HttpServletRequest) ec.getRequest()).getSession().setAttribute(
    				UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY, authToken.getName());
    
    		Authentication newAuth = authenticationManager.authenticate(authToken);
    		SecurityContextHolder.getContext().setAuthentication(newAuth);
    	} catch (UsernameNotFoundException unfe) {
    		FacesContext.getCurrentInstance().addMessage(null,
    				new FacesMessage(FacesMessage.SEVERITY_ERROR, unfe.getMessage(), unfe.getMessage()));
    	}
    
    	ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    	String encodedURL = ec.encodeResourceURL(ec.getRequestContextPath() + "/test.xhtml");
    
    	((HttpServletResponse) ec.getResponse()).sendRedirect(encodedURL);
    }
    I'm not using navigation rules and the login method is used from actionListener.

    Also, to make this work I had to remove the LoginController bean from faces-config and define it using spring:

    Code:
    <security:authentication-manager alias="authenticationManager">
    	<security:authentication-provider>
    		<security:user-service>
    			<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
    		</security:user-service>
    	</security:authentication-provider>
    </security:authentication-manager>
    <bean id="loginBean" class="test.LoginController" scope="session">
    	<property name="authenticationManager" ref="authenticationManager" />
    </bean>
    I've added the required alias to the authentication manager.

    For "remember me" to work you will need to call the rememberMeServices.loginSuccess(...).

    Best regards,
    Dumi.

  6. #16
    Join Date
    Jun 2009
    Location
    Timisoara
    Posts
    15

    Default

    I've just looked in Spring 3 sources and I've seen that UsernamePasswordAuthenticationFilter has a postOnly property. If you set this to false in the configuration file it should also work (with the original login method):

    Code:
        /**
         * Defines whether only HTTP POST requests will be allowed by this filter.
         * If set to true, and an authentication request is received which is not a POST request, an exception will
         * be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
         * will be called as if handling a failed authentication.
         * <p>
         * Defaults to <tt>true</tt> but may be overridden by subclasses.
         */
        public void setPostOnly(boolean postOnly) {
            this.postOnly = postOnly;
        }
    You can define custom filters in this way:
    Code:
    	<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
    		<filter-chain-map path-type="ant">
    			<filter-chain pattern="/**" filters="filter1,...,filterM,authenticationFilter",filterN,...,filterZ />
    		</filter-chain-map>
    	<bean>
    	<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="postOnly" value="false" />
    	</bean>
    And this in your web.xml:
    Code:
    	<!--Spring Security -->
    	<filter>
    		<filter-name>filterChainProxy</filter-name>
    		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>filterChainProxy</filter-name>
    		<url-pattern>/*</url-pattern>
    		<dispatcher>REQUEST</dispatcher>
    		<dispatcher>FORWARD</dispatcher>
    		<dispatcher>INCLUDE</dispatcher>
    		<dispatcher>ERROR</dispatcher>
    	</filter-mapping>
    	<!--Spring Security -->
    Or you can use the <custom-filter/> in <http/> as below:
    Code:
    	<security:http entry-point-ref="loginUrlAuthenticationEntryPoint">
    		<security:intercept-url pattern="/secured/**" access="ROLE_USER" />
    		<security:session-management>
    			<security:concurrency-control max-sessions="1" />
    		</security:session-management>
    		<security:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
    	</security:http>
    	<security:authentication-manager alias="authenticationManager">
    		<security:authentication-provider>
    			<security:user-service>
    				<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
    			</security:user-service>
    		</security:authentication-provider>
    	</security:authentication-manager>
    
    	<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="postOnly" value="false" />
    		<property name="authenticationSuccessHandler" ref="successHandler" />
    	</bean>
    
    	<bean id="successHandler"
    		class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    		<property name="defaultTargetUrl" value="/test.iface" />
    		<property name="alwaysUseDefaultTargetUrl" value="true" />
    	</bean>
    
    	<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    		<property name="loginFormUrl" value="/login.iface" />
    	</bean>
    
    	<bean id="loginBean" class="test.LoginController" scope="session">
    		<property name="authenticationManager" ref="authenticationManager" />
    	</bean>
    without changing anything in web.xml.

    Dumi.
    Last edited by Dumi; Apr 15th, 2010 at 08:35 AM.

  7. #17
    Join Date
    Jul 2009
    Location
    Düsseldorf, Germany
    Posts
    15

    Default

    Absolutely Great!!! Your Solution (not using j_spring_security_check) worked for me out of the box!!!

    Thank you very much! I owe you!

    Your second solution would make all the Tutorial from IceFaces working again with Spring Security 3. However I think Spring has restricted the default behaviour of the authenticationManager not accepting the GET method for a reason. Passwords don't belong into the URL and it has been always a dirty workaround for JSF. Therefore I prefere your first solution as best practice!

    neurox

  8. #18
    Join Date
    Jun 2009
    Location
    Timisoara
    Posts
    15

    Default

    I'm glad I could help! If you improve the login method code in any way please also post it.

    Thanks & best regards,
    Dumi.

  9. #19
    Join Date
    Jul 2009
    Location
    Düsseldorf, Germany
    Posts
    15

    Default

    I think it's pretty perfect apart from the hardcoded redirection. I think we should read the original target from Spring Security.

    However this is a minor issue and I haven't had the time yet to come up with a solution.

    Kind regards
    neurox

  10. #20
    Join Date
    Jun 2010
    Posts
    1

    Default

    Quote Originally Posted by Dumi View Post
    I've managed to make it work, but I'm not using j_spring_security_check anymore. Here is the updated code in my login bean:

    Code:
    public AuthenticationManager getAuthenticationManager() {
    	return authenticationManager;
    }
    
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
    	this.authenticationManager = authenticationManager;
    }
    
    public void login(ActionEvent e) throws IOException {
    	try {
    		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    		UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password);
    		authToken.setDetails(authentication.getDetails());
    
    		FacesContext context = FacesContext.getCurrentInstance();
    		ExternalContext ec = context.getExternalContext();
    		((HttpServletRequest) ec.getRequest()).getSession().setAttribute(
    				UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY, authToken.getName());
    
    		Authentication newAuth = authenticationManager.authenticate(authToken);
    		SecurityContextHolder.getContext().setAuthentication(newAuth);
    	} catch (UsernameNotFoundException unfe) {
    		FacesContext.getCurrentInstance().addMessage(null,
    				new FacesMessage(FacesMessage.SEVERITY_ERROR, unfe.getMessage(), unfe.getMessage()));
    	}
    
    	ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    	String encodedURL = ec.encodeResourceURL(ec.getRequestContextPath() + "/test.xhtml");
    
    	((HttpServletResponse) ec.getResponse()).sendRedirect(encodedURL);
    }
    I'm not using navigation rules and the login method is used from actionListener.

    Also, to make this work I had to remove the LoginController bean from faces-config and define it using spring:

    Code:
    <security:authentication-manager alias="authenticationManager">
    	<security:authentication-provider>
    		<security:user-service>
    			<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
    		</security:user-service>
    	</security:authentication-provider>
    </security:authentication-manager>
    <bean id="loginBean" class="test.LoginController" scope="session">
    	<property name="authenticationManager" ref="authenticationManager" />
    </bean>
    I've added the required alias to the authentication manager.

    For "remember me" to work you will need to call the rememberMeServices.loginSuccess(...).

    Best regards,
    Dumi.
    Hey! I'm new to those things and I'm getting the same problems discussed in this topic. Your solutions seems to work perfectly, but I can't understand some things:

    What's the name of this class?.. doing the "login()" method? LoginController?
    If it is LoginController and you removed from faces-config, how is your page calling the method with actionListener? I mean, if your remove the bean from faces-config, the page can't find the method, right?..

    Thanks..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •