Caros, saudações.
Uso Spring Security a algum tempo, e, decidi fazer uma aplicação, apenas par prática.
O detalhe é que a autenticação e login funcionam, porém ao acessar páginas que deveriam estar protegidas, o Spring permite normalmente, não disparando exceções ou mesmo redirecionando para página de acesso negado, como seria o esperado.
Abaixo segue meu código:
spring-security.xml:
<http pattern="/resources/**" security="none" />
<http auto-config="true" use-expressions="true">
<access-denied-handler error-page="/403" />
<form-login password-parameter="password" always-use-default-target="true" username-parameter="username" login-page="/login" default-target-url="/pages/protected/user/home.jsp" authentication-failure-url="/login?error" />
<logout logout-success-url="/" />
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="/pages/login.jsp" access="permitAll" />
<intercept-url pattern="/pages/protected/**" access="hasRole('ROLE_USER', 'ROLE_ADMIN')" />
<intercept-url pattern="/pages/protected/user/**" access="hasRole('ROLE_USER', 'ROLE_ADMIN')" />
<intercept-url pattern="/pages/protected/admin/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/**" access="permitAll" />
<logout logout-success-url="/login?logout" invalidate-session="true" delete-cookies="JSESSIONID" />
<csrf />
</http>
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" >
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
<authentication-manager alias="authenticationManager" erase-credentials="false" >
<authentication-provider user-service-ref="authenticationService" >
<password-encoder ref="encoder">
</password-encoder>
</authentication-provider>
</authentication-manager>
</code>
Classe para atuenticação:
@Service
@Transactional(readOnly=true)
public class AuthenticationService implements UserDetailsService {
@Autowired
private UsuarioService userService;
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
Usuario usuario;
try {
usuario = userService.loadUserByUsername(login);
CurrentUser currentUser = new CurrentUser(usuario);
return currentUser;
} catch (NegocioException e) {
e.printStackTrace();
throw new BadCredentialsException(e.getMessage(), e.getCause());
}
}
public void onApplicationEvent(AuthenticationSuccessEvent event) throws NegocioException {
String userName = ((UserDetails) event.getAuthentication().getPrincipal()).getUsername();
Usuario user = userService.loadUserByUsername(userName);
user.setUltimoLogin(new Date());
userService.registrarUltimoLogin(user);
}
/**
* Obtém o valor do atributo userService
* @return the userService
*/
public UsuarioService getUserService() {
return userService;
}
/**
* atribui o valor do atributo userService
* @param userService
*/
public void setUserService(UsuarioService userService) {
this.userService = userService;
}
}
Classe para controle de redirecionamento, no login:
@Controller
public class LoginController {
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam(value = "error", required = false) boolean error,
@RequestParam(value = "logout", required = false) boolean logout, HttpServletRequest request, HttpServletResponse response
,ModelMap model) {
if (error) {
model.addAttribute("mensagem", new Mensagem(getErrorMessage(request, "SPRING_SECURITY_LAST_EXCEPTION"), TipoMensagem.ERRO));
return new ModelAndView("login", model);
}
if (logout) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
model.addAttribute("mensagem", new Mensagem("Loggout efetuado com sucesso!", TipoMensagem.SUCESSO));
return new ModelAndView("login", model);
}
}
return new ModelAndView("/protected/user/home");
}
// for 403 access denied page
@RequestMapping(value = “/403”, method = RequestMethod.GET)
public ModelAndView accesssDenied() {
ModelAndView model = new ModelAndView();
// check if user is login
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetail = (UserDetails) auth.getPrincipal();
System.out.println(userDetail);
model.addObject("username", userDetail.getUsername());
}
model.setViewName("403");
return model;
}
// customize the error message
private String getErrorMessage(HttpServletRequest request, String key) {
Exception exception = (Exception) request.getSession().getAttribute(key);
return exception.getMessage();
}
}
ao digitar no navegador a palavra home, depois do nome da aplicação, o método abaixo seria chamado, como se espera, porém, sendo esta página protegida, mesmo não logado, o usuário é redirecionado.
@RequestMapping("/home")
public String home(Map model) {
return "/protected/user/home";
}
Gostaria de saber o que está errado.
Muito obrigado aos que puderem ajudar.