Piszę obecnie swój pierwszy projekt w Spring MVC i mam kilka podstawowych pytań. Ponieważ mój obecny kontroller wygląda tragicznie pod względem jakości
package com.jonki.Controller;
import com.jonki.DTO.LoginDTO;
import com.jonki.Entity.User;
import com.jonki.Service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class ApiController {
@Autowired
private UserService userService;
private Logger logger = LoggerFactory.getLogger(ApiController.class);
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(final Model model,
final HttpSession session,
final HttpServletRequest request) {
String usernameFromCookie = checkCookieUsername(request);
if (!usernameFromCookie.equals("")
&& session.getAttribute("user") != null) { // if exists cookie and session
logger.info("/login Go to /loginSuccessfully, bacause exists cookie and session");
return "redirect:/loginSuccessfully";
} else if (!usernameFromCookie.equals("")) { // if exists just cookie
User user = userService.getUserByUsername(usernameFromCookie);
session.setAttribute("user", user);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),
null,
AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
logger.info("/login Go to /loginSuccessfully, bacause exists cookie and I set session and principal security" + authenticationToken.getPrincipal());
return "redirect:/loginSuccessfully";
}
model.addAttribute("loginDTO", new LoginDTO());
logger.info("/login");
return "login";
}
@RequestMapping(value = "/loginSuccessfully", method = RequestMethod.GET)
public String loginSuccessfully(final HttpSession session,
final HttpServletRequest request,
final HttpServletResponse response,
final Model model) {
final String usernameFromCookie = checkCookieUsername(request);
final String loginStatusFromCookie = checkCookieLoginStatus(request);
if (usernameFromCookie.equals("")
&& !SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString().equals("anonymousUser")
&& (loginStatusFromCookie.equals("") || loginStatusFromCookie.equals("notLoggedIn"))) {
System.out.println("1");
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = ((org.springframework.security.core.userdetails.User) principal).getUsername();
User user = userService.getUserByUsername(username);
session.setAttribute("user", user);
Cookie cookieUsername = new Cookie("username", user.getUsername());
cookieUsername.setMaxAge(3600);
response.addCookie(cookieUsername);
Cookie cookieLoginStatus = new Cookie("loginStatus", "loggedIn");
cookieLoginStatus.setMaxAge(3600);
response.addCookie(cookieLoginStatus);
logger.info("/loginSuccessfully after /login");
} else if (usernameFromCookie.equals("")
&& SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString().equals("anonymousUser")) {
logger.info("/loginSuccessfully Go to /login, because don't exists cookie and principal security");
return "redirect:/login";
} else if(!usernameFromCookie.equals("")
&& session.getAttribute("user") == null) {
User user = userService.getUserByUsername(usernameFromCookie);
session.setAttribute("user", user);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),
null,
AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
logger.info("/loginSuccessfully I set session and principal security" + authenticationToken.getPrincipal());
}
logger.info("/loginSuccessfully");
return "loginSuccessfully";
}
@Secured("ROLE_USER")
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(final HttpSession session,
final HttpServletRequest request,
final HttpServletResponse response) {
session.removeAttribute("user");
SecurityContextHolder.clearContext();
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equalsIgnoreCase("username")) {
cookie.setMaxAge(0);
response.addCookie(cookie);
} else if (cookie.getName().equalsIgnoreCase("loginStatus")) {
cookie.setValue("notLoggedIn");
response.addCookie(cookie);
}
}
logger.info("Logout");
return "redirect:/login";
}
private String checkCookieUsername(final HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
String username = "";
for (Cookie cookie : cookies) {
if (cookie.getName().equalsIgnoreCase("username"))
username = cookie.getValue();
}
return username;
}
private String checkCookieLoginStatus(final HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
String loginStatus = "";
for (Cookie cookie : cookies) {
if (cookie.getName().equalsIgnoreCase("loginStatus"))
loginStatus = cookie.getValue();
}
return loginStatus;
}
}
i chciałbym go trochę rozpisać na osobne klasy. Czy jest sens tworzenia tylko osobnej klasy dla np. ustawiania sesji czy dodawania ciasteczek, albo np. ustawiania obiektu typu UsernamePasswordAuthenticationToken. If'y raczej muszą zostać, aby zabezpieczyć przed użytkownikami używającymi strony jak się chce.