-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello,
I have a web application using spring and spring security with java configuration. This work with jsp page but not with zul. I have no error, only "Chargement..." is display, without waiting. What is wrong in the code below ?
web.xml (I must have to remove "http" to post my question)
<web-app xmlns="://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="://xmlns.jcp.org/xml/ns/javaee ://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- Start ZK -->
<servlet>
<description>ZK loader for evaluating ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
<!-- End ZK -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>
300
</session-timeout>
</session-config>
</web-app>
HelloWordConfiguration.java
package test.sfs.springsecurity.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "test.sfs")
@Import(value = SecurityConfiguration.class)
@Order(1)
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {
@Bean(name="HelloWorld")
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
// viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".zul");
return viewResolver;
}
/*
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
SecurityConfiguration.java
package test.sfs.springsecurity.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").permitAll()
.usernameParameter("ssoId").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
}
SecurityWebApplicationInitializer.java
package test.sfs.springsecurity.configuration;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
SpringMvcInitializer.java
package test.sfs.springsecurity.configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { HelloWorldConfiguration.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/", "*" };
}
}
HelloWordController.java
package test.sfs.springsecurity.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HelloWorldController {
@RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("greeting", "Hi, Welcome to mysite");
return "welcome";
}
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String adminPage(ModelMap model) {
model.addAttribute("user", getPrincipal());
return "admin";
}
@RequestMapping(value = "/db", method = RequestMethod.GET)
public String dbaPage(ModelMap model) {
model.addAttribute("user", getPrincipal());
return "dba";
}
@RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
public String accessDeniedPage(ModelMap model) {
model.addAttribute("user", getPrincipal());
return "accessDenied";
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
return "login";
}
@RequestMapping(value="/logout", method = RequestMethod.GET)
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login?logout";
}
private String getPrincipal(){
String userName = null;
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
userName = ((UserDetails)principal).getUsername();
} else {
userName = principal.toString();
}
return userName;
}
}
pom.xml (I must have to remove "http" to post my question)
<project xmlns="://maven.apache.org/POM/4.0.0" xmlns:xsi="://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="://maven.apache.org/POM/4.0.0 ://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test-sfs</groupId>
<artifactId>sfs-test</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>sfs-test</name>
<properties>
<springframework.version>4.2.6.RELEASE</springframework.version>
<springsecurity.version>4.1.0.RELEASE</springsecurity.version>
<zk.version>8.0.0</zk.version>
<zkspring.version>3.2.0</zkspring.version>
<!--<zkspring.security.version>3.2.0</zkspring.security.version>-->
<spring-release-train.version>Hopper-SR1</spring-release-train.version>
<spring-data.version>1.10.1.RELEASE</spring-data.version>
<hibernate.version>4.3.7.Final</hibernate.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springsecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Start zk -->
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkplus</artifactId>
<version>${zk.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkbind</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkspring-core</artifactId>
<version>${zkspring.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkspring-security</artifactId>
<version>${zkspring.security.version}</version>
</dependency>
-->
<!-- End zk -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- Spring Data -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>${spring-release-train.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.artifactId}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>${project.artifactId}</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
With or without web.xml, the result is the same ...
If, in HelloWordConfiguration, I replace viewResolver.setSuffix(".zul");
by viewResolver.setSuffix(.jsp");
my login page is diplayed.
Thanks.
Hi Catzk,
Do you get any error in your browser's java console when stuck on the "chargement" spinner? Try to look if the page is missing any resources. While the login page should be public with this configuration, it might be trying to load resources from a private location.
You may have to allow non-zul documents served through [your webapp]/zkau/ to guests, as the UI packages will be loaded from there.
If you get any Javascript error in your console, can you send it here too?
Regards, MDuchemin
Check adding this to your configuration:
<sec:http use-expressions="true" auto-config="true">
<sec:headers>
<sec:frame-options policy="SAMEORIGIN"/>
</sec:headers>
<sec:csrf disabled="true"/>
...
</sec:http>
Hello MDuchemin,
There is effectively error messages in console :
GET
....://localhost:8081/sfs-test/login [HTTP/1.1 200 OK 21 ms]
SyntaxError: expected expression, got '<' zk.wpd:1:0
SyntaxError: expected expression, got '<' zul.lang.wpd:1:0
SyntaxError: expected expression, got '<' zkbind.wpd:1:0
GET
....://localhost:8081/sfs-test/zkau/web/af058fa0/zul/css/zk.wcs [HTTP/1.1 302 Found 3 ms]
GET
....://localhost:8081/sfs-test/login [HTTP/1.1 200 OK 10 ms]
ReferenceError: zk is not defined login:16:1"
And if I try again :
ReferenceError: zkmx is not defined login:16
For information, login.zul and login.jsp are in the same folder.
http:// (image description)
For arcangelSalazar, I add .and().headers().frameOptions().sameOrigin();
in the SecurityConfiguration.java and comment .and().csrf()
by I have always the same error ...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// .antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").permitAll()
.usernameParameter("userName").passwordParameter("password")
// .and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and().headers().frameOptions().sameOrigin();
}
Hi Catzk,
It looks like the packages call are receiving something else. If you look at the network tab and check the response for these packages, I would guess that they have been redirected to the authentication page instead. (in this case, instead of javascript, the reply would be the html document for the login page, or a redirect call to said page).
ZK requires these packages to render a zul page, and cannot function if the end user do not have access to them. (JSP pages do not require additional javascript resources unless you explicitly include them, which explain why the JSP login page can be rendered) All of these resources should be loaded from the /zkau/* path.
The simplest way to make these packages available to the end user would be to make the /zkau/ uri public by removing spring-security filtering on them. important note: if you create a custom package containing zul files and include this custom package in your classpath, some included zul pages may be served through this uri. In this case, a more robust solution would be to make all documents except ".zul" files public under /zkau/*.
MDuchemin,
I add .antMatchers("/zkau/**").permitAll()
and my login page is now diplay. BUT my stylesheet is not loaded and when I submit my login page, I have the error message
Request method 'POST' not supported
Here is my login page :
<?xml version="1.0" encoding="UTF-8"?>
<zk xmlns=".ttp://www.zkoss.org/2005/zul"
xmlns:h="native"
xmlns:xsi=".ttp://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=".ttp://www.zkoss.org/2005/zul .ttp://www.zkoss.org/2005/zul/zul.xsd">
<window border="none" width="100%" height="100%">
<borderlayout height="100%">
<center border="none" flex="true" autoscroll="true"
sclass="main-body" style="padding: 5px">
<box align="center" pack="center">
<h:form name="loginForm" action="login" method="POST">
<hlayout>
<div width="20px">
</div>
<label value="test login zul" sclass="banner-head" />
</hlayout>
<separator spacing="30px" />
<zk if="${param.error != null}">
<label value="${labels.login_failed} : ${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}" style="color:red; font-size:1.5em;" />
<separator spacing="30px" />
</zk>
<h:table>
<h:tr>
<h:td>
<label value="Utilisateur"/>
</h:td>
<h:td>
<textbox name="username" focus="true" />
</h:td>
</h:tr>
<h:tr>
<h:td>
<separator spacing="20px" />
</h:td>
</h:tr>
<h:tr>
<h:td>
<label value="Mot de passe"/>
</h:td>
<h:td>
<textbox type="password" name="password"/>
</h:td>
</h:tr>
<h:tr>
<h:td>
<separator spacing="50px" />
</h:td>
</h:tr>
<h:tr>
<h:td colspan="2" align="center">
<h:input type="submit" value="Submit"/>
</h:td>
</h:tr>
</h:table>
</h:form>
</box>
</center>
</borderlayout>
</window>
</zk>
An idea ?
Hi Catzk,
I see that your security declaration include:
@RequestMapping(value = "/login", method = RequestMethod.GET)
and your login form has a post method:
<h:form name="loginForm" action="login" method="POST">
I think that changing your form method to GET should help with this error.
You mentioned that your stylesheet isn't loaded, did you get any error in the dev tools? Any unresolved resources in the network tab? I would recommend trying to load the stylesheet directly in your browser. If you can just navigate to it, then there is probably an issue in the page link to the stylesheet. If you are redirected or denied, then you will need to fix that in order to display the retrieve the stylesheet when accessing the login page.
Regards, MDuchemin
Hi MDuchemin,
I change POST to GET in my login.zul but it's the login.zul that is displayed again when I submit. I also try with "RequestMethod.POST" in my controller but nothing change. In the login.jsp, it's also a POST and that work !
For the stylesheet, it's OK. I add a "permitAll" on the folder that contains my css file.
Thanks.
Hi Catzk,
Not sure if it helps, but someone had a similar issue here: http://forum.zkoss.org/question/66693/zk-using-both-get-and-post-at-the-same-time/
It look like their issue was solved by using:
method = {RequestMethod.GET,RequestMethod.POST}
Does this have any effect on your problem?
Regards, MDuchemin
Asked: 2016-05-27 11:34:50 +0800
Seen: 142 times
Last updated: Jun 02 '16
ZK Calendar Wire Spring-managed Beans Failed [closed]
Spring security doesn't return user inside event listener
where to put @Transactional (Hibernate Spring)
Clustered Session Terracotta not working
Can't inject using @Value in ViewModel if not declaring as @Component.. so what do we use?
Not able to bind Spring beans after zk upgrade
retriving Spring authentication provider Name dynamically in multiple authentication providers