Bonjour,

je n'arrive pas à faire un simple système d'authentification (login,mdp) avec Tapestry 5.3 et Tapestry-spring-security.

Les pages sont bien bloquées mais la connexion ne fonctionne pas !

Voici le code->

pom.xml:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
<tapestry-spring-security-version>3.0.0-SNAPSHOT</tapestry-spring-security-version>
 
<dependency>
	<groupId>nu.localhost.tapestry</groupId>
	<artifactId>tapestry-spring-security</artifactId>
	<version>${tapestry-spring-security-version}</version>
</dependency>
 
<repositories>
		<repository>
			<id>tapestry.security.snapshots</id>
			<url>http://www.localhost.nu/java/mvn-snapshot</url>
			<releases>
				<enabled>false</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
	</repositories>

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
public class UserDetailsServiceImpl implements UserDetailsService {
 
	private static final Logger logger = LoggerFactory
			.getLogger(UserDetailsServiceImpl.class);
 
	@Inject
	@Property
	private UserManager userManager;
 
	public UserDetailsServiceImpl(PasswordEncoder encoder, SaltSource salt) {
		System.out.println("ici");
	}
 
	/**
         * @see UserDetailsService
         */
	public UserDetails loadUserByUsername(String name)
			throws UsernameNotFoundException, DataAccessException {
		System.out.println(name);
		User user = null;
		try {
			user = userManager.findByName(name);
		} catch (NoResultException e) {
			user = null;
		} catch (EmptyResultDataAccessException e) {
			user = null;
		}
		return user;
	}
 
}
AppModule.java:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
 
package capteur.administration.web.services;
 
import java.io.IOException;
 
import nu.localhost.tapestry5.springsecurity.services.RequestInvocationDefinition;
 
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.ioc.services.ServiceOverride;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.core.userdetails.UserDetailsService;
 
import capteur.administration.web.services.security.UserDetailsServiceImpl;
import capteur.administration.web.utils.PropertiesFileSymbolProvider;
 
/**
 * This module is automatically included as part of the Tapestry IoC Registry,
 * it's a good place to configure and extend Tapestry, or to place your own
 * service definitions.
 */
public class AppModule {
 
	public static UserDetailsService buildUserDetailsService(
			@Inject PasswordEncoder encoder, @Inject SaltSource salt) {
		return new UserDetailsServiceImpl(encoder, salt);
	}
 
	public static void contributeProviderManager(
			OrderedConfiguration<AuthenticationProvider> configuration,
			@InjectService("DaoAuthenticationProvider") AuthenticationProvider daoAuthenticationProvider) {
 
		configuration.add("daoAuthenticationProvider",
				daoAuthenticationProvider);
	}
 
	public static void contributeFilterSecurityInterceptor(
			Configuration<RequestInvocationDefinition> configuration) {
		configuration.add(new RequestInvocationDefinition(
				"/home/**", "ROLE_USER "));
		configuration.add(new RequestInvocationDefinition("/Statistic/**",
				"ROLE_ADMIN"));
	}
 
	@Contribute(ServiceOverride.class)
	public static void setupApplicationServiceOverrides(
			MappedConfiguration<Class, Object> configuration) {
		configuration.add(PasswordEncoder.class, new ShaPasswordEncoder());
	}
 
	public static void contributeFactoryDefaults(
			MappedConfiguration<String, Object> configuration) {
		// The application version number is incorprated into URLs for some
		// assets. Web browsers will cache assets because of the far future
		// expires
		// header. If existing assets are changed, the version number should
		// also
		// change, to force the browser to download new versions. This overrides
		// Tapesty's default
		// (a random hexadecimal number), but may be further overriden by
		// DevelopmentModule or
		// QaModule.
		configuration.override(SymbolConstants.APPLICATION_VERSION,
				"1.0-SNAPSHOT");
	}
 
	public static void contributeApplicationDefaults(
			MappedConfiguration<String, Object> configuration) {
		// Contributions to ApplicationDefaults will override any contributions
		// to
		// FactoryDefaults (with the same key). Here we're restricting the
		// supported
		// locales to just "en" (English). As you add localised message catalogs
		// and other assets,
		// you can extend this list of locales (it's a comma separated series of
		// locale names;
		// the first locale name is the default when there's no reasonable
		// match).
		configuration.add("tapestry.start-page-name", "Login");
		configuration.add("tapestry.compress-whitespace", "false");
		configuration.add("tapestry.production-mode", "false");
		configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,fr");
		configuration.add("spring-security.failure.url", "/login/failed");
		configuration.add("spring-security.accessDenied.url", "/login/failed");
		configuration.add("spring-security.check.url",
				"/j_spring_security_check");
		configuration.add("spring-security.target.url",
				"/home");
		configuration.add("spring-security.afterlogout.url", "/login");
		configuration.add("spring-security.rememberme.key", "REMEMBERMEKEY");
		configuration.add("spring-security.loginform.url", "/login");
		configuration.add("spring-security.force.ssl.login", "false");
		configuration.add("spring-security.anonymous.key", "acegi_anonymous");
		configuration.add("spring-security.anonymous.attribute",
				"anonymous,ROLE_ANONYMOUS");
		configuration.add("spring-security.password.salt", "DEADBEEF");
	}
 
	/**
         * This is a service definition, the service will be named "TimingFilter".
         * The interface, RequestFilter, is used within the RequestHandler service
         * pipeline, which is built from the RequestHandler service configuration.
         * Tapestry IoC is responsible for passing in an appropriate Logger
         * instance. Requests for static resources are handled at a higher level, so
         * this filter will only be invoked for Tapestry related requests.
         * <p/>
         * <p/>
         * Service builder methods are useful when the implementation is inline as
         * an inner class (as here) or require some other kind of special
         * initialization. In most cases, use the static bind() method instead.
         * <p/>
         * <p/>
         * If this method was named "build", then the service id would be taken from
         * the service interface and would be "RequestFilter". Since Tapestry
         * already defines a service named "RequestFilter" we use an explicit
         * service id that we can reference inside the contribution method.
         */
	public RequestFilter buildTimingFilter(final Logger log) {
		return new RequestFilter() {
			public boolean service(Request request, Response response,
					RequestHandler handler) throws IOException {
				long startTime = System.currentTimeMillis();
 
				try {
					// The responsibility of a filter is to invoke the
					// corresponding method
					// in the handler. When you chain multiple filters together,
					// each filter
					// received a handler that is a bridge to the next filter.
 
					return handler.service(request, response);
				} finally {
					long elapsed = System.currentTimeMillis() - startTime;
 
					log.info(String.format("Request time: %d ms", elapsed));
				}
			}
		};
	}
 
	/**
         * This is a contribution to the RequestHandler service configuration. This
         * is how we extend Tapestry using the timing filter. A common use for this
         * kind of filter is transaction management or security. The @Local
         * annotation selects the desired service by type, but only from the same
         * module. Without @Local, there would be an error due to the other
         * service(s) that implement RequestFilter (defined in other modules).
         */
	public void contributeRequestHandler(
			OrderedConfiguration<RequestFilter> configuration,
			@Local RequestFilter filter) {
		// Each contribution to an ordered configuration has a name, When
		// necessary, you may
		// set constraints to precisely control the invocation order of the
		// contributed filter
		// within the pipeline.
 
		configuration.add("Timing", filter);
	}
 
	// public static void contributeSymbolSource(
	// OrderedConfiguration<SymbolProvider> providers) {
	// providers.add("springSecurity", new ClasspathResourceSymbolProvider(
	// "security.properties"));
	//
	// }
 
	// make configuration from 'site.properties' on the filesystem available
	// as symbols
	public PropertiesFileSymbolProvider buildClasspathPropertiesFileSymbolProvider(
			Logger logger) {
		return new PropertiesFileSymbolProvider(logger, "site.properties",
				true);
	}
 
	public static void contributeSymbolSource(
			OrderedConfiguration<SymbolProvider> configuration,
 
			@InjectService("ClasspathPropertiesFileSymbolProvider") SymbolProvider classpathPropertiesFileSymbolProvider)
 
	{
		configuration.add("ClasspathPropertiesFile",
				classpathPropertiesFileSymbolProvider,
				"after:SystemProperties", "before:ApplicationDefaults");
 
	}
}
Login.java:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
public class Login {
 
	@Inject @Value("${spring-security.check.url}")
	private String checkUrl;
 
	@Inject
	private Request request;
 
	private boolean failed = false;
 
	public boolean isFailed() {
		return failed;
	}
 
	public String getLoginCheckUrl() {
		return request.getContextPath() + checkUrl;
	}
 
	@OnEvent("activate")
	public void onActivate(String extra) {
		if (extra.equals("failed")) {
			failed = true;
		}
	}
 
}
Login.tml:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
	xmlns:p="tapestry:parameter">
 
 
 
<body>
	<div class="container">
 
		<div id="login">
			<t:form t:id="loginForm" action="${loginCheckUrl}" method="post">
				<t:if test="failed">${message:connect-failed}<br />
				</t:if>
				<fieldset>
					<legend>${message:connect}</legend>
					<div class="control-group">
						<label class="control-label" for="j_username">${message:login}:</label>
						<div class="controls">
							<input type="text" id="j_username" name="j_username" value=""
								maxlength="30" />
						</div>
					</div>
					<div class="control-group">
						<label class="control-label" for="j_password">${message:password}:</label>
						<div class="controls">
							<input type="password" id="j_password" name="j_password" value=""
								maxlength="30" />
						</div>
					</div>
					<div class="form-actions">
						<input type="submit" class="btn btn-primary"
							value="${message:connect}" />
					</div>
				</fieldset>
			</t:form>
		</div>
	</div>
</body>
</html>
User.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 
@Entity
public class User implements UserDetails {
 
	/**
         * 
         */
	private static final long serialVersionUID = 1L;
 
	@Id
	@GeneratedValue(strategy = IDENTITY)
	private int id;
 
	@Column(unique = true, nullable = false)
	private String login;
 
	@Column(nullable = false)
	private String password;
 
	@ManyToMany
	private Set<Role> roles;
 
	@OneToMany(mappedBy = "user")
	private List<ActivityLog> activitiesLog = new ArrayList<ActivityLog>();
 
	public User() {
 
	}
 
	public User(String login, String password) {
		this.login = login;
		this.password = password;
		System.out.println(login);
	}
 
	public String getLogin() {
		return login;
	}
 
	public void setLogin(String login) {
		this.login = login;
	}
 
	public String getPassword() {
		return password;
	}
 
	public void setPassword(String password) {
		this.password = password;
	}
 
	public int getId() {
		return id;
	}
 
	public void setId(int id) {
		this.id = id;
	}
 
	public void addActivityLog(ActivityLog activityLog) {
		this.activitiesLog.add(activityLog);
	}
 
	public List<ActivityLog> getActivitiesLog() {
		return activitiesLog;
	}
 
	public void setActivitiesLog(List<ActivityLog> activitiesLog) {
		this.activitiesLog = activitiesLog;
	}
 
	@Override
	public String getUsername() {
		// TODO Auto-generated method stub
		return null;
	}
 
	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}
 
	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}
 
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}
 
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}
 
	public boolean isAdmin() {
		boolean result = false;
		for (Role authority : roles) {
			if ("ROLE_ADMIN".equals(authority.getAuthority())) {
				result = true;
			}
		}
		return result;
	}
 
	public Set<Role> getRoles() {
		return roles;
	}
 
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
 
	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(
				roles.size());
		for (Role role : roles) {
			GrantedAuthority ga = role;
			auths.add(ga);
		}
		return auths;
	}
 
}
Role.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 
@Entity
public class Role implements GrantedAuthority {
 
 
 
	private static final long serialVersionUID = -1803599999277426176L;
 
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(nullable = false, name = "id_authority")
	private Long id;
 
	@Column(nullable = false)
	private String authority;
 
	public Role() {
		super();
	}
 
	public Role(String authority) {
		super();
		this.setAuthority(authority);
	}
 
	public String getAuthority() {
		return authority;
	}
 
	public void setAuthority(String authority) {
		this.authority = authority;
	}
 
	public Long getId() {
		return id;
	}
 
	public void setId(Long id) {
		this.id = id;
	}
 
	@Override
	public int hashCode() {
		return authority.hashCode();
	}
 
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (obj instanceof String)
			return obj.equals(authority);
		if (getClass() != obj.getClass())
			return false;
		final Role other = (Role) obj;
		if (authority == null) {
			if (other.authority != null)
				return false;
		} else if (!authority.equals(other.authority))
			return false;
		return true;
	}
 
	public int compareTo(Object o) {
		if (this == o)
			return 0;
		if (o == null)
			return -1;
		if (o.getClass() == String.class)
			return authority.compareTo((String) o);
		if (getClass() != o.getClass())
			return -1;
		final Role other = (Role) o;
		if (authority == null) {
			if (other.authority != null)
				return 1;
		} else
			return authority.compareTo(other.authority);
		return -1;
	}
}
Merci d'avance pour votre aide !