SpringBoot tokenRepository,JdbcTokenRepository not save in table persistence_logins - spring-boot

Login work, but table persitence_logins remain empty.
I Follow the documentation here :
https://courses.baeldung.com/courses/learn-spring-security-the-starter-class/lectures/924437
Don't know how to change.
I need to Override something else ?
persistent_logins
username varchar(64) not null,
series varchar(64) primary key,
token varchar(65) not null,
last_used timestamp not null
SECURITY CONFIG
package com.example.java.configuration;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.sql.DriverManager;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
private DataSource dataSource;
private final String USERS_QUERY = "select email, password, active from user where email=?";
private final String ROLES_QUERY = "select u.email, r.role from user u inner join user_role ur on (u.id = ur.user_id) inner join role r on (ur.role_id=r.role_id) where u.email=?";
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.usersByUsernameQuery(USERS_QUERY)
.authoritiesByUsernameQuery(ROLES_QUERY)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/dottore").hasAuthority("DOTTORE")
.antMatchers("/home/**").hasAnyAuthority("USER").anyRequest()
.authenticated().and().csrf().disable()
.formLogin().loginPage("/login").usernameParameter("email").passwordParameter("password")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/home/home")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.and().rememberMe()
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60*60)
.and().exceptionHandling().accessDeniedPage("/access_denied");
}
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
}
APPLICATION PROPERTIES
#Peristence
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=pass
# hibernate configurations
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialet= org.hibernate.dialect.MySQL5Dialect
# thumeleaf configurations
spring.thymeleaf.mode= LEGACYHTML5
spring.thymeleaf.cache=false
USER CONTROLLER:
package com.example.java.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.example.java.model.User;
import com.example.java.service.UserService;
import sun.jvm.hotspot.runtime.Threads;
import java.util.concurrent.TimeUnit;
#Controller
public class UserController {
#Autowired
private UserService userService;
#RequestMapping("/")
public ModelAndView main(){
ModelAndView model = new ModelAndView();
model.setViewName("user/login");
return model;
}
#RequestMapping(value= {"/login"}, method=RequestMethod.GET)
public ModelAndView login() {
ModelAndView model = new ModelAndView();
model.setViewName("user/login");
return model;
}
#RequestMapping(value= {"/signup"}, method=RequestMethod.GET)
public ModelAndView signup() {
ModelAndView model = new ModelAndView();
User user = new User();
model.addObject("user", user);
model.setViewName("user/signup");
return model;
}
#RequestMapping(value= {"/signup"}, method=RequestMethod.POST)
public ModelAndView createUser(#Valid User user, BindingResult bindingResult) throws InterruptedException {
ModelAndView model = new ModelAndView();
User userExists = userService.findUserByEmail(user.getEmail());
if(userExists != null) {
bindingResult.rejectValue("email", "error.user", "This email already exists!");
}
if(bindingResult.hasErrors()) {
model.setViewName("user/signup");
} else {
userService.saveUser(user);
model.addObject("msg", "User has been registered successfully!");
model.addObject("user", new User());
model.setViewName("user/signup");
}
return model;
}
#RequestMapping(value= {"/home/home"}, method=RequestMethod.GET)
public ModelAndView home() {
ModelAndView model = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
model.addObject("userName", user.getNome() + " " + user.getCognome());
model.setViewName("home/home");
return model;
}
#RequestMapping(value= {"/access_denied"}, method=RequestMethod.GET)
public ModelAndView accessDenied() {
ModelAndView model = new ModelAndView();
model.setViewName("errors/access_denied");
return model;
}
}

EDIT:
RESOLVED.
In security config I put:
.and().rememberMe().rememberMeParameter("my-remember-me")
And in login.html
<input type="checkbox" class="form-check-input" name="my-remember-me" id="remember-me" />

Related

Registration Issue with Spring Security 401 with Postman

I had problem in spring security when I try to register a new user and tested it in the postman it keep giving me a 401 unauthorized response.
I checked all the filters, control, service repository and everything I already checked all the issues here and even searched a lot about it in google but no answer I hope some one had the answer.
this is the code below:
this is the Security Configuration:
package app.gym.v1.Utility.Config;
import app.gym.v1.Utility.Filter.JwtAccessDeniedHandler;
import app.gym.v1.Utility.Filter.JwtAuthenticationEntryPoint;
import app.gym.v1.Utility.Filter.JwtAuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import static app.gym.v1.Utility.Constant.SecurityConstant.*;
import static org.springframework.security.config.http.SessionCreationPolicy.*;
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private JwtAuthorizationFilter jwtAuthorizationFilter;
private JwtAccessDeniedHandler jwtAccessDeniedHandler;
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
public SecurityConfig(
JwtAuthorizationFilter jwtAuthorizationFilter,
JwtAccessDeniedHandler jwtAccessDeniedHandler,
JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint,
#Qualifier("userDetailsService")UserDetailsService userDetailsService,
BCryptPasswordEncoder bCryptPasswordEncoder) {
this.jwtAuthorizationFilter = jwtAuthorizationFilter;
this.jwtAccessDeniedHandler = jwtAccessDeniedHandler;
this.jwtAuthenticationEntryPoint = jwtAuthenticationEntryPoint;
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().and()
.sessionManagement().sessionCreationPolicy(STATELESS)
.and().authorizeRequests().antMatchers(PUBLIC_URLS).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().accessDeniedHandler(jwtAccessDeniedHandler)
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
}
#Bean
#Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
}
this is the Resource code:
package app.gym.v1.Resource;
import app.gym.v1.Model.User;
import app.gym.v1.Service.UserService;
import app.gym.v1.Utility.Exception.Domain.*;
import app.gym.v1.Utility.Exception.ExceptionHandling;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import static org.springframework.http.HttpStatus.OK;
#RestController
#RequestMapping(path = {"/","/user"})
public class UserControl extends ExceptionHandling {
private UserService userService;
#Autowired
public UserControl(UserService userService) {
this.userService = userService;
}
#PostMapping("/register")
public ResponseEntity<User> register(#RequestBody User user) throws UserNotFoundException, UsernameExistException, EmailExistException, IOException {
User newUser = userService.register(user.getUsername(), user.getEmail(), user.getPassword(), user.getRole());
return new ResponseEntity<>(newUser, OK);
}
}
this is the user implementation service:
package app.gym.v1.Utility.Impl;
import app.gym.v1.Model.User;
import app.gym.v1.Model.UserPrincipal;
import app.gym.v1.Repo.UserRepo;
import app.gym.v1.Service.UserService;
import app.gym.v1.Utility.Exception.Domain.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import static app.gym.v1.Utility.Constant.UserImplConstant.*;
import static app.gym.v1.Utility.Enums.Role.*;
import static org.apache.commons.lang3.StringUtils.*;
#Service
#Transactional
#Qualifier("UserDetailsService")
public class UserServiceImpl implements UserService, UserDetailsService {
private Logger LOGGER = LoggerFactory.getLogger(getClass());
private UserRepo userRepo;
private BCryptPasswordEncoder passwordEncoder;
#Autowired
public UserServiceImpl(UserRepo userRepo, BCryptPasswordEncoder passwordEncoder) {
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepo.findUserByUsername(username);
if (user == null) {
LOGGER.error("User with this phone number does not exist: " + username);
throw new UsernameNotFoundException("User with this phone number does not exist: " + username);
}else {
user.setLastLoginDateDisplay(user.getLastLoginDate());
user.setLastLoginDate(new Date());
userRepo.save(user);
UserPrincipal userPrincipal = new UserPrincipal(user);
LOGGER.info("Retrieving user with this phone number" + username);
return userPrincipal;
}
}
#Override
public User register(String username, String email, String password, String role) throws UserNotFoundException, UsernameExistException, EmailExistException {
validateNewUsernameAndEmail(EMPTY, username, email);
User user = new User();
user.setUserId(generateUserId());
user.setUsername(username);
user.setEmail(email);
user.setPassword(encodePassword(password));
user.setRole(USER.name());
user.setAuthorities(USER.getAuthorities());
user.setJoinDate(new Date());
user.setActive(true);
user.setNotLocked(true);
userRepo.save(user);
return user;
}
private String encodePassword(String password) {
return passwordEncoder.encode(password);
}
private String generateUserId() {
return RandomStringUtils.randomNumeric(20);
}
private String generatePassword() {
return RandomStringUtils.randomAlphanumeric(20);
}
private User validateNewUsernameAndEmail(String currentUsername, String newUsername, String newEmail) throws UserNotFoundException, UsernameExistException, EmailExistException {
User userByNewUsername = findUserByUsername(newUsername);
User userByNewEmail = findUserByEmail(newEmail);
if(isNotBlank(currentUsername)) {
User currentUser = findUserByUsername(currentUsername);
if(currentUser == null) {
throw new UserNotFoundException(NO_USER_FOUND_BY_USERNAME + currentUsername);
}
if(userByNewUsername != null && !currentUser.getId().equals(userByNewUsername.getId())) {
throw new UsernameExistException(USERNAME_ALREADY_EXISTS);
}
if(userByNewEmail != null && !currentUser.getId().equals(userByNewEmail.getId())) {
throw new EmailExistException(EMAIL_ALREADY_EXISTS);
}
return currentUser;
} else {
if(userByNewUsername != null) {
throw new UsernameExistException(USERNAME_ALREADY_EXISTS);
}
if(userByNewEmail != null) {
throw new EmailExistException(EMAIL_ALREADY_EXISTS);
}
return null;
}
}
}
the problem is with the registration my route is that(localhost:8080/user/register) or (localhost:8080/register).
I put a constant for them to make a public urls.
You need to annotate your SecurityConfig class with #Configuration or it won't be picked up.
If you do not have a custom security configuration set up properly, the application will use the default Spring Boot autoconfiguration which restricts access to all endpoints.

How to combine spring boot oauth2 with custom user accounts?

This here is my first post to stack overflow (after plenty of reading), so I'm going to do my best to get it right. I've been looking up this problem for weeks and haven't found an answer to it, but I happily admit that there's a possibility I'm not looking up the right terms. I'm self-taught, so I sometimes miss things.
I have a Spring Boot application with custom user accounts stored in a postgres database. I would like to add OAuth2 support to that application. I have been able to successfully add OAuth2 login, but I would like to intercept that OAuth2 user information and use it to access one of my custom user accounts.
User signs into Github OAuth -> Server accesses OAuth details and retrieves matching user account info from my user database.
My ideal workflow would be to intercept the OAuth2 details and retrieve the custom info from my DB before the user is redirected to the protected page or back to the index.
Hopefully I managed to include all of the relevant code snippets below. In case I missed anything, the full project can be seen on this here github repository: https://github.com/Ahimsaka/shorturl2.
Web Security Config
package com.github.ahimsaka.shorturl.security;
import com.github.ahimsaka.shorturl.service.impl.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
auth.userDetailsService(userDetailsService());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().ignoringAntMatchers("/url", "/user/registration", "/user/resetPassword", "/user/savePassword", "login/oauth2/code/github")
.and()
.authorizeRequests()
.antMatchers("/user").hasAnyAuthority("USER", "ADMIN")
.antMatchers("/user/registration", "/u/*", "/login*", "/forgotPassword",
"/user/resetPassword", "user/savePassword").permitAll()
.antMatchers(HttpMethod.POST, "/url").permitAll()
.antMatchers("/delete/**").hasAnyAuthority("ADMIN", "USER")
.antMatchers("/admin").hasAuthority("ADMIN")
.antMatchers("/u/*").permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/user", true)
.permitAll()
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.oauth2Login();
}
}
Index With Github Login Link
<!DOCTYPE html>
<html xmlns:th="http:/www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Index</title>
</head>
<body>
Index
<div sec:authorize="isAuthenticated()">
Welcome <b><span sec:authentication="name">Username</span></b>
<i><span sec:authentication="principal.authorities">Roles</span></i>
<form th:action="#{/logout}" method="post">
    <input type="submit" value="Logout" />
</div>
<div sec:authorize="isAuthenticated() == false">
<input type="button" value="Login" />
With GitHub: click here
</div>
<div align="center">
<h1>Shorten My URL</h1>
<br />
<form action="#" th:action="#{/url}"
method="post">
<table border="0" cellpadding="10">
<tr>
<td>URL:</td>
<td><input type="text" name="url"/></td>
</tr>
<tr>
<td colspan="2"><button type="submit">Save</button></td>
</tr>
</table>
</form>
<div sec:authorize="hasAuthority('ADMIN')">Admin</div>
<div sec:authorize="hasAuthority('USER')">User</div>
</div>
</body>
</html>
Registration Controller - Where I would LIKE the Magic to Happen
package com.github.ahimsaka.shorturl.controller;
import com.github.ahimsaka.shorturl.dto.PasswordDto;
import com.github.ahimsaka.shorturl.dto.UserDto;
import com.github.ahimsaka.shorturl.entity.User;
import com.github.ahimsaka.shorturl.entity.VerificationToken;
import com.github.ahimsaka.shorturl.exception.UserAlreadyExistException;
import com.github.ahimsaka.shorturl.exception.UserNotFoundException;
import com.github.ahimsaka.shorturl.exception.util.GenericResponse;
import com.github.ahimsaka.shorturl.registration.OnRegistrationCompleteEvent;
import com.github.ahimsaka.shorturl.service.UserSecurityService;
import com.github.ahimsaka.shorturl.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.MessageSource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.reactive.result.view.RedirectView;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.net.http.HttpRequest;
import java.util.Calendar;
import java.util.Locale;
import java.util.Optional;
import java.util.UUID;
#RestController
public class RegistrationController {
private final Logger log = LoggerFactory.getLogger(RegistrationController.class);
private UserService userService;
private ApplicationEventPublisher applicationEventPublisher;
private MessageSource messages;
private JavaMailSender mailSender;
private UserSecurityService userSecurityService;
RegistrationController(UserService userService, ApplicationEventPublisher applicationEventPublisher,
MessageSource messages, JavaMailSender mailSender, UserSecurityService userSecurityService) {
this.userService = userService;
this.messages = messages;
this.applicationEventPublisher = applicationEventPublisher;
this.mailSender = mailSender;
this.userSecurityService = userSecurityService;
}
#GetMapping("/user/registration")
public ModelAndView showRegistrationForm() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("registration");
UserDto userDto = new UserDto();
modelAndView.getModel().put("user", userDto);
return modelAndView;
}
#PostMapping("/user/registration")
public ModelAndView registerUserAccount(#ModelAttribute("user") #Valid UserDto userDto,
HttpServletRequest request, Errors errors) {
try {
User registered = userService.registerNewUserAccount(userDto);
String appUrl = request.getContextPath();
applicationEventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), appUrl));
} catch (UserAlreadyExistException uaeEx) {
ModelAndView mav = new ModelAndView("registration", "user", userDto);
mav.addObject("message", "An account for that username/email already exists.");
return mav;
} catch (RuntimeException ex) {
return new ModelAndView("emailError", "user", userDto);
}
return new ModelAndView("successRegister", "user", userDto);
}
#GetMapping("/registrationConfirm")
public ModelAndView confirmRegistration(WebRequest request,
#RequestParam("token") String token) {
ModelAndView mav = new ModelAndView();
Locale locale = request.getLocale();
VerificationToken verificationToken = userService.getVerificationToken(token);
if (verificationToken == null) {
String message = messages.getMessage("auth.message.invalidToken", null, locale);
mav.setViewName("badUser");
mav.getModel().put("message", message);
return mav;
}
User user = verificationToken.getUser();
Calendar cal = Calendar.getInstance();
if ((verificationToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
String messageValue = messages.getMessage("auth.message.expired", null, locale);
mav.setViewName("badUser");
mav.getModel().put("message", messageValue);
mav.getModel().put("token", token);
mav.getModel().put("expired", true);
return mav;
}
user.setEnabled(true);
userService.saveRegisteredUser(user);;
mav.setViewName("login");
mav.getModel().put("message", messages.getMessage("message.accountVerified", null, locale));
return mav;
}
#GetMapping("/user/resendRegistrationToken")
public GenericResponse resendRegistrationToken(HttpServletRequest request,
#RequestParam("token") String existingToken) {
VerificationToken newToken = userService.generateNewVerificationToken(existingToken);
User user = userService.getUser(newToken.getToken());
SimpleMailMessage email = constructResendVerificationTokenEmail(getAppUrl(request), request.getLocale(), newToken, user);
mailSender.send(email);
return new GenericResponse(messages.getMessage("message.resendToken", null, request.getLocale()));
}
#PostMapping("/user/resetPassword")
public ModelAndView resetPassword(HttpServletRequest request, #RequestParam("email") String userEmail) {
User user = userService.findByUsername(userEmail);
if (user == null) {
throw new UserNotFoundException();
}
String token = UUID.randomUUID().toString();
userService.createPasswordResetTokenForUser(user, token);
mailSender.send(constructResetTokenEmail(getAppUrl(request), request.getLocale(), token, user));
ModelAndView mav = new ModelAndView("login");
mav.getModel().put("message", messages.getMessage("message.resetPasswordEmail", null, request.getLocale()));
return mav;
}
#GetMapping("/user/changePassword")
public ModelAndView showChangePasswordPage(Locale locale, #RequestParam("token") String token) {
ModelAndView mav = new ModelAndView();
String result = userSecurityService.validatePasswordResetToken(token);
if (result != null) {
String message = messages.getMessage("auth.message." + result, null, locale);
mav.getModel().put("message", message);
mav.setViewName("login");
} else {
mav.getModel().put("password", new PasswordDto());
mav.getModel().put("token", token);
mav.setViewName("updatePassword");
}
return mav;
}
#PostMapping("/user/savePassword")
public ModelAndView savePassword(HttpServletRequest request,
#ModelAttribute("password") #Valid PasswordDto passwordDto) {
ModelAndView mav = new ModelAndView();
String result = userSecurityService.validatePasswordResetToken(passwordDto.getToken());
if (result != null) {
mav.setViewName("updatePassword");
mav.getModel().put("message", messages.getMessage("auth.message." + result, null, request.getLocale()));
return mav;
}
Optional user = userService.getUserByPasswordResetToken(passwordDto.getToken());
if (user.isPresent()) {
userService.changeUserPassword((User) user.get(), passwordDto.getNewPassword(), passwordDto.getToken());
mav.setViewName("login");
mav.getModel().put("message", messages.getMessage("message.resetPasswordSuc", null, request.getLocale()));
} else {
mav.setViewName("updatePassword");
mav.getModel().put("message", messages.getMessage("auth.message.invalid", null, request.getLocale()));
}
return mav;
}
#GetMapping("/forgotPassword")
private ModelAndView forgotPasswordPage() {
return new ModelAndView("forgotPassword");
}
#GetMapping("login/oauth2/code/github")
// This does nothing but I haven't removed it yet.
private ModelAndView oauthUserSignIn(HttpServletRequest request, Authentication authentication) {
return new ModelAndView("user");
}
// NON API
private SimpleMailMessage constructResendVerificationTokenEmail (String contextPath, Locale locale, VerificationToken newToken, User user){
String url = contextPath + "/registrationConfirm?token=" + newToken.getToken();
String message = messages.getMessage("message.resendToken", null, locale);
return constructEmail("Resend Registration Token", message + " \r\n" + url, user);
}
private SimpleMailMessage constructResetTokenEmail(String contextPath, Locale locale, String token, User user) {
String url = contextPath + "/user/changePassword?token=" + token;
String message = messages.getMessage("message.resetPassword", null, locale);
return constructEmail("Reset Password", message + " \r\n" + url, user);
}
private SimpleMailMessage constructEmail(String subject, String body, User user) {
SimpleMailMessage email = new SimpleMailMessage();
email.setSubject(subject);
email.setText(body);
email.setTo(user.getUsername());
return email;
}
private String getAppUrl(HttpServletRequest request) {
return "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}

Deployed Spring App is not getting routed to correct URL on first logins

I deployed a Spring App to Heroku. I am using Spring Security for logging in and registration. My problem is that for new users, when they initially log-in, it takes them to the base URL (the URL that Heroku gave me for my site). All of my main html files are in a folder named "cheese". The problem is that it directs me to the main URL (instead of "/cheese/account", which is where I direct it to be routed in my SecurityConfig), and I get a white label error.
This only happens the first time. When they log on again, it takes them to the correct URL, which is "/cheese/account". Also, once in a while, I will click on the base URL that heroku gave for my site, and it gives me just that URL, and doesn't direct me to "/cheese/login". This will happen if I try to access the URL from an incognito window.
I dont have this problem at all when running it locally. Here is the relevant code...Let me know if you need anything, in addition.
SecurityConfig
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select email as principal, password as credentials, true from customer where email=?")
.authoritiesByUsernameQuery("select customer_email as principal, role_id as role from user_roles where customer_email=?")
.passwordEncoder(passwordEncoder()).rolePrefix("ROLE_");
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http
.csrf().disable()
.authorizeRequests()
.antMatchers(
"/**/webjars/**",
"/cheese/signup",
"/cheese/login",
"/cheese/success").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/cheese/login")
.defaultSuccessUrl("/cheese/account")
.permitAll();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
UserController
package com.example.demo.controllers;
import com.example.demo.models.Customer;
import com.example.demo.models.data.CustomerDao;
import com.example.demo.models.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("cheese")
public class UserController {
#Autowired
private CustomerDao customerDao;
#Autowired
UserService userService;
#RequestMapping(value = "login")
public String loginPage(Model model) {
model.addAttribute("title", "Login Page");
model.addAttribute("customer", new Customer());
return "cheese/login";
}
#RequestMapping(value = "account")
public String accountInfo(Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Customer customer = customerDao.findByEmail(authentication.getName());
model.addAttribute("name", customer.getName());
model.addAttribute("customer", customer);
return "cheese/account";
}
#GetMapping("signup")
public String displaySignUpForm(Model model) {
model.addAttribute("title", "Sign Up");
model.addAttribute("customer", new Customer());
return "cheese/signup";
}
#PostMapping(value = "signup")
public String processSignUp(Model model, #ModelAttribute Customer customer, Errors errors) {
if (errors.hasErrors()) {
return "cheese/signup";
}
userService.createUser(customer);
return "cheese/success";
}
}
MainController
package com.example.demo.controllers;
import com.example.demo.models.Cheese;
import com.example.demo.models.data.CheeseDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RequestMapping(value = "cheese")
#Controller
public class MainController {
#Autowired
CheeseDao cheeseDao;
#RequestMapping(value = "")
public String hello(Model model) {
model.addAttribute("title", "Grocery List");
model.addAttribute("cheeses", cheeseDao.findAll());
return "cheese/index";
}
#GetMapping("add")
public String displayAddCheeseForm(Model model) {
model.addAttribute("title", "Add Cheese");
model.addAttribute("cheese", new Cheese());
return "cheese/add";
}
#PostMapping("add")
public String processAddCheeseForm(Model model,
#ModelAttribute #Valid Cheese cheese,
Errors errors) {
if (errors.hasErrors()) {
return "cheese/add";
}
cheeseDao.save(cheese);
return "redirect:";
}
#RequestMapping(value = "remove", method = RequestMethod.GET)
public String displayRemoveCheeseForm(Model model) {
model.addAttribute("cheeses", cheeseDao.findAll());
model.addAttribute("title", "Remove Cheese");
return "cheese/remove";
}
#RequestMapping(value = "remove", method = RequestMethod.POST)
public String processRemoveCheeseForm(Model model, #RequestParam int[] cheeseIds) {
for (int id : cheeseIds) {
cheeseDao.deleteById(id);
}
return "redirect:";
}
}

How to get jwt token string on service layer when user request first time using jwt, Oauth2, spring security?

I am new in development of micro-services with jwt.
Here is my project structure:
First micro-service is used to authenticate users by jwt and Oauth2
using username and password. This microservice is called auth-service.
Login request url is like:
[http://localhost:9092/oauth/token?username=s#sawai.com&password=randomPassword&grant_type=password][1]
By calling this url we got jwt token like:
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsib2F1dGgyX2lkIl0sInVzZXJfbmFtZSI6InNAc2F3YWkuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sInRlbmFudElkIjoic2F3YWkuY29tIiwic3lzdGVtR2VuZXJhdGVkUGFzc3dvcmQiOnRydWUsImlkIjoiNTYzOTFhYzAtZDc4OC00ODEyLThmYWMtODEwZTIyMjdjYmI1IiwiZXhwIjoxNTI0NzMxNzgwLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImY0ZTNmNTM5LWRkNDgtNGMxMy05OTg5LTcwM2E1NWYxMjNlYyIsImVtYWlsIjoic0BzYXdhaS5jb20iLCJjbGllbnRfaWQiOiJ0cnVzdGVkLWFwcCJ9.AS1tXpUcPMgEw63FrvPP-xGBz7qCi14Eqe29rDzTXPg","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsib2F1dGgyX2lkIl0sInVzZXJfbmFtZSI6InNAc2F3YWkuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sImF0aSI6ImY0ZTNmNTM5LWRkNDgtNGMxMy05OTg5LTcwM2E1NWYxMjNlYyIsInRlbmFudElkIjoic2F3YWkuY29tIiwic3lzdGVtR2VuZXJhdGVkUGFzc3dvcmQiOnRydWUsImlkIjoiNTYzOTFhYzAtZDc4OC00ODEyLThmYWMtODEwZTIyMjdjYmI1IiwiZXhwIjoxNTI0NzQ2MTgwLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjI1ZmJlY2IyLWRhODgtNDY1ZS1iM2I2LTFlN2NmYjBlYmVjMiIsImVtYWlsIjoic0BzYXdhaS5jb20iLCJjbGllbnRfaWQiOiJ0cnVzdGVkLWFwcCJ9.jSG5zUBzu9yGqnBueU7fkIZV6XhXD8oCkYCerwHkkOw","expires_in":14399,"scope":"read write","tenantId":"sawai.com","systemGeneratedPassword":true,"id":"56391ac0-d788-4812-8fac-810e2227cbb5","email":"s#sawai.com","jti":"f4e3f539-dd48-4c13-9989-703a55f123ec"}
On auth service database we just create a single table called users with following fields:
id varchar(255)
created_on datetime
last_modified_date datetime
email varchar(255)
enabled bit(1)
password varchar(255)
role varchar(255)
system_generated_password bit(1)
tenant_id varchar(255)
validate bit(1)
OK.
Now another micro-service is called company and in company service we have list of users(not same as auth service users, because auth service contains users for multiple micro-services like: Company, Candidate etc).
Now we want to maintain last_logged_on for company users. So admin can check when an user logged in last time.
What we try to do is: When user login using auth service and user type is company user then call company service and update users last_logged_on. For calling company service we need jwt-access-token because urls are secure on company side. So how can we get access token on auth service when we request to get jwt token.
Here is configuration for jwt with spring boot on auth side.
package com.cs.je.auth.config.jwt;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
/**
* #author sawai
*
*/
#Configuration
#EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
#Value("${auth.token.time}")
private int accessTokenValiditySeconds;
#Value("${refresh.token.time}")
private int refreshTokenValiditySeconds;
#Value("${security.oauth2.resource.id}")
private String resourceId;
#Value("${trusted.app.name}")
private String trustedAppName;
#Value("${trusted.app.secret}")
private String trustedAppSecret;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private CustomAccessTokenConverter customAccessTokenConverter;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(this.authenticationManager)
.tokenServices(tokenServices())
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter());
}
#Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
// we're allowing access to the token only for clients with 'ROLE_TRUSTED_CLIENT' authority
//.tokenKeyAccess("permitAll()")
.tokenKeyAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(trustedAppName)
.authorizedGrantTypes("client_credentials", "password", "refresh_token")
.authorities("ROLE_TRUSTED_CLIENT")
.scopes("read", "write")
.resourceIds(resourceId)
// .accessTokenValiditySeconds(accessTokenValiditySeconds)
// .refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.secret(trustedAppSecret);
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
System.out.println("3333333333333");
DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
tokenConverter.setUserTokenConverter(new DefaultUserAuthenticationConverter() {
#Override
public Authentication extractAuthentication(Map<String, ?> map) {
Authentication authentication = super.extractAuthentication(map);
System.out.println("222222222222");
// User is my custom UserDetails class
User user = new User();
user.setTenantId(map.get("tenantId").toString());
user.setEmail(map.get("email").toString());
user.setId(map.get("id").toString());
//user.setPassword(map.get("password").toString());
//System.out.println("date " + );
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.addAll(authentication.getAuthorities());
user.setGrantedAuthorities(authorities);
user.setRole(Role.valueOf(authorities.iterator().next().toString()));
//user.setSpecialKey(map.get("specialKey").toString());
return new UsernamePasswordAuthenticationToken(user,
authentication.getCredentials(), authentication.getAuthorities());
}
});
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("key");
converter.setAccessTokenConverter(customAccessTokenConverter);
converter.setAccessTokenConverter(tokenConverter);
return converter;
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
defaultTokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds);
defaultTokenServices.setReuseRefreshToken(false);
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
return defaultTokenServices;
}
}
Here is Custom Token Enhance:
package com.cs.je.auth.config.jwt;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
import com.cs.je.auth.rest.api.call.CustomRestTemplate;
import com.cs.je.auth.service.UserService;
import com.cs.je.auth.utils.EncTokenUtils;
import com.cs.je.auth.utils.UserUtils;
/**
* #author sawai
*
*/
#Component
public class CustomTokenEnhancer implements TokenEnhancer {
#Autowired
private UserService userService;
#Autowired
private CustomRestTemplate customRestTemplate;
#Value("${microservice.company.protocol}")
private String protocol;
#Value("${microservice.company.port}")
private String port;
#Value("${microservice.company.ip}")
private String ipAddress;
#Value("${microservice.company.user.api}")
private String userCreateUrl;
#Autowired
private TokenStore tokenStore;
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<>();
if (authentication != null) {
User user = (User)authentication.getPrincipal();
additionalInfo.put("email", user.getEmail());
additionalInfo.put("tenantId", user.getTenantId());
additionalInfo.put("id", user.getId());
if (user.isSystemGeneratedPassword()) {
additionalInfo.put("systemGeneratedPassword", true);
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
System.out.println(accessToken.getRefreshToken());
System.out.println(accessToken.getRefreshToken().getValue());
System.out.println(accessToken.getTokenType());
/*if (user.getRole().equals(Role.ROLE_ADMIN) || user.getRole().equals(Role.ROLE_USER)) {
String token = accessToken.toString();
try {
System.out.println("before call");
//ResponseEntity<Object> responseEntity = customRestTemplate.exchange(protocol + "://" + ipAddress + ":" + port + userCreateUrl + "/" + user.getId() + "/last-loggedOn", token, EncTokenUtils.getEncToken(user.getEmail()), HttpMethod.PUT, null);
System.out.println("successfull");
} catch (Exception e) {
e.printStackTrace();
}
}*/
System.out.println("1111111111");
}
return accessToken;
}
}
Security Config
package com.cs.je.auth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.cs.je.auth.constant.Constants;
import com.cs.je.auth.enums.Role;
import com.cs.je.auth.model.User;
import com.cs.je.auth.repository.UserRepository;
import com.cs.je.auth.service.UserService;
/**
* #author sawai
*
*/
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Autowired
private UserRepository userRepository;
/*#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST ,"/user/**").hasAnyAuthority("ROLE_SUPER_USER", "ROLE_ADMIN")
.anyRequest().authenticated();
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
httpSecurity.requestCache().requestCache(new NullRequestCache());
httpSecurity.httpBasic();
//httpSecurity.addFilterBefore(CORSFilter, ChannelProcessingFilter.class);
}*/
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
if (userRepository.count() < 1) {
User user = new User();
user.setEmail("jeAdmin#email.com");
user.setPassword("jeAdminUser");
user.setTenantId(Constants.JE_TENANT_ID);
user.setRole(Role.ROLE_SUPER_USER);
user.setValidate(true);
userService.create(user, null);
}
}
#Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/api/candidate/**");
webSecurity.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
webSecurity.ignoring().antMatchers("/api/company/**");
webSecurity.ignoring().antMatchers("/api/forgotPassword/**");
//webSecurity.ignoring().antMatchers(HttpMethod.POST, "/oauth/**");
}
}
ResourceConfig.java
package com.cs.je.auth.config.jwt;
/**
* #author sawai
*
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.savedrequest.NullRequestCache;
import com.cs.je.auth.filter.CORSFilter;
#Configuration
#EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {
#Value("${security.oauth2.resource.id}")
private String resourceId;
// The DefaultTokenServices bean provided at the AuthorizationConfig
#Autowired
private DefaultTokenServices tokenServices;
// The TokenStore bean provided at the AuthorizationConfig
#Autowired
private TokenStore tokenStore;
#Autowired
private CORSFilter corsFilter;
// To allow the rResourceServerConfigurerAdapter to understand the token,
// it must share the same characteristics with AuthorizationServerConfigurerAdapter.
// So, we must wire it up the beans in the ResourceServerSecurityConfigurer.
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(resourceId)
.tokenServices(tokenServices)
.tokenStore(tokenStore);
}
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/api/candidate/**");
// webSecurity.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
// webSecurity.ignoring().antMatchers(HttpMethod.POST, "/oauth/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/").permitAll().and().authorizeRequests().antMatchers("/console/**")
.permitAll().and().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().and()
// when restricting access to 'Roles' you must remove the "ROLE_" part role
// for "ROLE_USER" use only "USER"
//.antMatchers("/api/hello").access("hasAnyRole('USER')")
//.antMatchers("/api/admin").hasRole("ADMIN")
.authorizeRequests().antMatchers(HttpMethod.POST ,"/api/user/**").hasAnyAuthority("ROLE_SUPER_USER", "ROLE_ADMIN")
// restricting all access to /api/** to authenticated users
//.antMatchers("/**")
//.antMatchers("/api/**").authenticated();
.anyRequest().authenticated();
http.csrf().disable();
http.headers().frameOptions().disable();
http.requestCache().requestCache(new NullRequestCache());
http.httpBasic();
http.addFilterBefore(corsFilter, ChannelProcessingFilter.class);
}
}
All above config is on auth service side.
Now when user request for jwt token on auth, then we want to get access-token value on service layer, so i can call company service by secure url calling.
Please guide me how can we get access-token value when user request for jwt token. If you look in CustomTokenEnhancer then we tried to print access-token there by using following statements:
**System.out.println(accessToken.getRefreshToken());
System.out.println(accessToken.getRefreshToken().getValue());
System.out.println(accessToken.getTokenType());**
But values are similar to: 642e0cf2-9214-42d8-ae85-29e5cdfccef1
But we want actual token here.
Please guide me.
You can use that method
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String TOKEN_SEPERATOR = " ";
public static String getAccessToken(){
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
return Arrays.asList(request.getHeader(AUTHORIZATION_HEADER).split(TOKEN_SEPERATOR)).get(1);
}
return null;
}

User is not stored in the database Spring

I write application on Spring with security. I made database with users and I can Login in app as user from database. But when I try to register new user in DB it don't stored.
I have no errors, just redirect to main page.
If I uncomment autologin string I get Null Point EX.
Here is structure of my app:
UserServiceImpl.class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
import com.ya.pokupay.dao.RoleDAO;
import com.ya.pokupay.dao.UserDAO;
import com.ya.pokupay.model.Role;
import com.ya.pokupay.model.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserDAO userDao;
#Autowired
private RoleDAO roleDao;
#Override
public void save(User user) {
System.out.println("HERE");
Set<Role> roles = new HashSet<>();
roles.add(roleDao.getOne(1L));
user.setRoles(roles);
System.out.println("user: " + user);
userDao.save(user);
}
#Override
public User findByUsername(String username) {
return userDao.findByUsername(username);
}
}
controller method:
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute("userForm") User userForm, BindingResult bindingResult, Model model) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.save(userForm);
//securityService.autoLogin(userForm.getUsername(), userForm.getConfirmPassword());
return "redirect:/all";
}
UserDetailServiceImpl:
import com.ya.pokupay.dao.UserDAO;
import com.ya.pokupay.model.Role;
import com.ya.pokupay.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.Set;
public class UserDetailsServiceImpl implements UserDetailsService{
#Autowired
private UserDAO userDao;
#Override
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUsername(username);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
}
If it can help I can add some more code or settings.
EDITED:
UserDAO:
import com.ya.pokupay.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDAO extends JpaRepository<User, Long> {
User findByUsername(String username);
}
I didn't find solution, so I just wrote my own implementation of asve method and it works for me.

Resources