How to set the Session using Spring boot - spring-boot

i am creating simple login programming using seesion.iam a beginner of spring boot how to set the seesion if the username and password correct below it is work successfully if the username and password correct vist to the home page.how to set the session . i want show the seesion on index page.logout also needed
Login
#PostMapping("/login")
public String login(#ModelAttribute("user") User user ) {
if(Objects.nonNull(oauthUser))
{
((User) httpSession).getUsername();
return "redirect:/";
} else {
return "redirect:/login";
}
}
index.html
<h2>Welcome<h2>

You can inject session info directy with
#Autowired
private HttpSession httpSession;
and to get id httpSession.getId()

Related

Spring boot Authentication Failure Handler - Custom with no additional url or query parameters

My current implementation of Spring Boot Login is as follows:
login.html:
<div class="error-message m-l-4" th:if="${errorMessage}" th:text="${errorMessage}"></div>
WebSecurityConfigurerAdapter - configure method:
formLogin().failureUrl("/login-error")
RequestMapper:
#RequestMapping("/")
public class Root {
#GetMapping("login")
public ModelAndView getLoginView(ModelMap mav) {
return new ModelAndView("login", mav);
}
#GetMapping("login-error")
public RedirectView setErrorMessage(RedirectAttributes attributes) {
attributes.addFlashAttribute("errorMessage", "Username or Password is invalid");
return new RedirectView("login");
}
}
The above is working perfectly when the user inputs invalid credentials the error is displayed on HTML. However, is there a way to accomplish the same result but get rid of the extra directory /login-error? I don't want it to be accessible despite redirecting to the login page with the error. I have tried to translate a custom AuthenticationFailureHandler (.failureHandler(new CustomAuthenticationFailureHandler())) to have the same effect but I can only return JSON not HTML. Basically, I want the exact same behavior as the Instagram Login Page.
See Pages in Order and upon Refresh back to the exact page as Page 1:

Spring : How to use session in Spring MVC

I have a login form and I want to display Name of user who logined .I want to use session in Spring MVC, but it's not work
This is UsersController
#PostMapping("/room/saveRegister")
public String saveRegister(#Valid Users users, BindingResult result, RedirectAttributes redirect) {
if (result.hasErrors()) {
return "register";
}
usersService.save(users);
redirect.addFlashAttribute("success", "Saved user successfully!");
return "redirect:/room";
}
#GetMapping("/room/login")
public String login(Model model) {
model.addAttribute("users", new Users());
return "login";
}
#PostMapping("/room/loginRoom")
public String login(#ModelAttribute("users") Users user, ModelMap modelMap, RedirectAttributes redirect,HttpSession session) {
if(usersService.findByEmailAndPass(user.getEmail(),user.getPass()) != null) {
session.setAttribute("name",user.getName());
return "redirect:/room";
}else {
modelMap.put("error", "Email or Password is not correct. Pleased Try Again");
return "login" ;
}
}
And in file .html,I add
<li ><span th:text ="${session.name}"></span></li>
But when I login successful . Name of User is not display . Session is not work. I don't know why
You need to use ${sessionScope.name} instead of ${session.name}
More details can be found at Examples of EL Expressions
Refer this
Using Http Session With Spring Based Web Applications

logout specific session Id in spring security

in spring security:
i think with tow way logout called: when a session timeout occurred or a user logout itself...
anyway in these ways , destroyedSession called in HttpSessionEventPublisher and SessionRegistry remove SessionInformation from sessionIds list...
when i use below method for force logout specific user , this method just "expired" SessionInformation in SessionRegistry. now when i get all online user "getAllPrincipals()" from SessionRegistry, the user that session expired, is in the list!
#Override
public boolean forceLogOut(int userId){
for (Object username: sessionRegistry.getAllPrincipals()) {
User temp = (User) username;
if(temp.getId().equals(userId)){
for (SessionInformation session : sessionRegistry.getAllSessions(username, false)) {
session.expireNow();
}
}
}
return true;
}
how can i logout 'specific user' or 'sessionId' that session object remove from "Web Server" and "Session Registry" ?
i googling and found HttpSessionContext in Servlet API that can get HttpSession from specific sessionId. and then invalidate session. but i think this method is not completely useful!
(note. this class is deprecated!)
what is the best way? Whether I'm wrong?
Try like this:
#RequestMapping(value="/logout", method = RequestMethod.GET)
public String logoutPage (HttpServletRequest request, HttpServletResponse response){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
//new SecurityContextLogoutHandler().logout(request, response, auth);
persistentTokenBasedRememberMeServices.logout(request, response, auth);
SecurityContextHolder.getContext().setAuthentication(null);
}
return "redirect:/login?logout";
}
To logout specific session Id check that link:
how to log a user out programmatically using spring security

How to customize the behavior of session scoped bean by current user is Spring MVC

Consider following scenario: Spring Security authenticates login data against custom UserDetailsServiceimplementation as follows
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
UserProfile profile = users.find(name);
if (profile.getUsername().equals("admin"))
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new User(profile.getUsername(), profile.getPassword(), authorities);
}
If authentication succeeds, I want to create unique session scoped service in controller, with customized behavior by valid UserProfile object state. I guess best way to do that is to declare the session bean manually in configuration file and somehow autowire UserProfile or session owner to it's constructor, but how that's possible, when UserProfile is not even an managed object?
In this case, I want server to create service for authenticated user, which maintains SSH connection to remote host with credentials stored in UserProfile
Also, how to restrict a creation of such service just to post login? Is there way to achieve this kind of behavior, or is it actually bad architecture?
You can use the SecurityContextHolder to access the authenticated user for the current request. I think the best approach is to create a singleton Service with a method like this:
public UserDetails getCurrentUser() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
return (UserDetails) principal;
} else {
//handle not authenticated users
return null;
}
}
Now you can autowire and use the service in your controllers.

UserDetails getPassword returns null in spring security 3.1. How to get password of currently logged in user?

I have implemented change password functionality using spring security but ((UserDetails) principal).getPassword()) is returning null for logged in user.
If I remember correctly, this used to work earlier in 3.0. Was this changed in 3.1 so that the current password of the logged in user cannot be retrieved?
In the below code I am checking the current password typed in user password from the web page. I am then checking if the logged in user's password matches the typed in password. If it does then I want to set oldPasswordMatchNewPassword = true.
How do I implement this functionality?
#RequestMapping(value = "/account/changePassword.do", method = RequestMethod.POST)
public String submitChangePasswordPage(
#RequestParam("oldpassword") String oldPassword,
#RequestParam("password") String newPassword) {
Object principal = SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
String username = principal.toString();
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
System.out.println("username: " + username);
System.out.println("password: "
+ ((UserDetails) principal).getPassword());
if (((UserDetails) principal).getPassword() != null) {
if (((UserDetails) principal).getPassword().equals(oldPassword)) {
oldPasswordMatchNewPassword = true;
}
}
}
if (oldPasswordMatchNewPassword == true) {
logger.info("Old password matches new password. Password will be updated.");
changePasswordDao.changePassword(username, newPassword);
SecurityContextHolder.clearContext();
return "redirect:home.do";
} else {
logger.info("Old password did not match new password. Password will be not be updated.");
return null;
}
}
I put a couple of sysout()s so that I can see the values returned.
For ((UserDetails) principal).getUsername() I can see the correct logged in user.
((UserDetails) principal).getPassword() it is returning null.
How do I get ((UserDetails) principal).getPassword() this value?
Thanks in advance!
I used this block of code (erase-credentials="false") to fix this. I do not know if this is an elegant solution but it fixed my problem:
<authentication-manager alias="authenticationManager" erase-credentials="false">
<!-- authentication-provider user-service-ref="userService" -->
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource" />
</authentication-provider>
</authentication-manager>
Yes, this has changed in version 3.1. Credentials are cleared after a successfull authentication by default. You can set eraseCredentialsAfterAuthentication to false on the ProviderManager to prevent this.
See details here: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/core-services.html#core-services-erasing-credentials
Since the password isn't retained in memory after the user has been authenticated (generally a good thing), you would need to explicitly reload it in order to use it. An alternative and more flexible strategy is to inject an instance of the AuthenticationManager and use that directly:
String name = SecurityContextHolder.getContext().getAuthentication();
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(name, oldPassword));
// Update password here with your dao
} catch (AuthenticationException e) {
// Old password was wrong
}
that way you don't need to worry about things like password-encoding strategies. Note that you shouldn't be storing passwords in plain text. They should be hashed using bcrypt or something similar.

Resources