Thanks for your help so far. I think I'm almost there, could you please take a look at the code, since I'm just guessing a bit how to fix this.
The URL that should be responded to is /member/activate.htm?code=12345
where member 2 has activationCode 12345
(Spring 2.5)
spring-security.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<http auto-config="true" lowercase-comparisons="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
<!-- URLs -->
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/member/activated.htm" access="ROLE_ANONYMOUS,ROLE_USER"/>
<intercept-url pattern="/**" access="ROLE_ANONYMOUS,ROLE_USER" />
<form-login
login-page="/login.htm"
login-processing-url="/processLogin"
authentication-failure-url="/login.htm?login_error=1"
always-use-default-target="false"
default-target-url="/index.htm"
/>
<logout logout-url="/logout" />
</http>
<authentication-provider user-service-ref="securityService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
<beans:bean id="hashAuthenticationProvider" class="nl.sticky.website.web.HashAuthenticationProvider">
<custom-authentication-provider/>
</beans:bean>
<global-method-security />
<beans:bean id="authenticationProcessingFilter" class="nl.sticky.website.web.HashProcessingFilter">
<custom-filter position="LAST" />
<custom-authentication-provider/>
<beans:property name="defaultTargetUrl" value="/index.htm" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<authentication-manager alias="authenticationManager"/>
<beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<beans:property name="loginFormUrl" value="/login.htm" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
</beans:beans>
HashProcessingFilter
Code:
public class HashProcessingFilter extends AuthenticationProcessingFilter implements ApplicationEventPublisherAware {
private final SecurityService securityService;
@Autowired
public HashProcessingFilter(SecurityService ss) {
securityService = ss;
}
@Override
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if(!request.getRequestURI().endsWith("/member/activated.htm") && !request.getRequestURI().endsWith("/member/changePassword.htm")) {
chain.doFilter(request, response);
return;
}
String hash = ServletRequestUtils.getStringParameter(request, "code");
if(hash == null) {
chain.doFilter(request, response);
return;
}
HashToken paat = new HashToken(hash);
try {
Authentication auth = new HashAuthenticationProvider(securityService).authenticate(paat);
SecurityContextHolder.getContext().setAuthentication(auth);
} catch(Exception e) {
System.out.println(e);
}
chain.doFilter(request, response);
}
}
HashAuthenticationProvider
Code:
public class HashAuthenticationProvider implements AuthenticationProvider {
private SecurityService securityService;
@Autowired
public HashAuthenticationProvider(SecurityService ss) {
this.securityService = ss;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String hash = (String) authentication.getPrincipal();
Member member = securityService.getMemberByHash(hash);
if(member == null) {
throw new BadCredentialsException("The user with hash " + hash + " could not be found.");
}
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(member.getUsername(), null);
return token;
}
@SuppressWarnings("unchecked")
@Override
public boolean supports(Class authentication) {
return HashToken.class.equals(authentication);
}
}