AuthenticationController.java
/**
* TFG 75.678 - TFG Desarrollo web 2020 e-Learning for Schools
* Copyright (C) 2020 Eduardo Rodriguez Carro
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.uoc.tfg.sel.web;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.CurrentSecurityContext;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.uoc.tfg.sel.repository.model.User;
import org.uoc.tfg.sel.security.JwtUtil;
import org.uoc.tfg.sel.security.model.AuthenticationRequest;
import org.uoc.tfg.sel.security.model.AuthenticationResponse;
import org.uoc.tfg.sel.security.model.JWTToken;
import org.uoc.tfg.sel.security.model.UserDetailsExtended;
import org.uoc.tfg.sel.service.SessionService;
/**
* Controlador de autenticacion
*
* @author Eduardo Rodriguez Carro
*
*/
@RestController
@CrossOrigin
@RequestMapping("/auth")
public class AuthenticationController {
/**
* tiempo maximo de vida de la sesion
*/
@Value("${security.session.token.lifetime:31536000000}")
private Long tokenLifeTime;
/**
* Autenticador de Spring Security
*/
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private SessionService sessionService;
/**
* Utilidades de JWT
*/
@Autowired
private JwtUtil jwtUtil;
/**
* Endpoint de logout
*
* @param uuid ide a retornar
*
* @return retorna siempre estado OK
*/
@RequestMapping(value = "/logout", method = RequestMethod.POST)
public ResponseEntity<Void> logout(@CurrentSecurityContext(expression = "authentication.principal") UserDetailsExtended userDetails) {
if(userDetails != null) {
sessionService.logout(userDetails.getSessionId());
}
return ResponseEntity.ok().build();
}
/**
* Endpoint de login
*
* @param authenticationRequest
* @return
* @throws Exception
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<AuthenticationResponse> login(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
// Autenticamos con el API del framework
// En caso de error el proceso del API sale por error
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()));
// Si hemos autenticado, obtenemos el nombre del usuario del objeto de usuario encapsulado en el UserDetails de Spring
User user = null;
UserDetailsExtended userAuthentication = null;
if (authentication.getPrincipal() instanceof UserDetailsExtended) {
userAuthentication = (UserDetailsExtended) authentication.getPrincipal();
user = userAuthentication.getUser();
} else {
user = (User) authentication.getPrincipal();
}
// Borramos la password por seguridad
user.setPassword(null);
Map<String,Object> claims = new HashMap<>();
String sessionId = sessionService.generateSession();
if(userAuthentication !=null) {
userAuthentication.setSessionId(sessionId);
}
claims.put(JWTToken.SESSION_ID, sessionId);
// Generamos el token JWT firmado
String token = jwtUtil.generateToken(claims,user.getLogin(),tokenLifeTime);
AuthenticationResponse response = new AuthenticationResponse();
response.setUser(user);
response.setToken(token);
// Respondemos con el estado OK
return ResponseEntity.ok(response);
}
}