Spring Security - Redirect to entered url after success login - spring-boot

I have been working on Spring Security
I use a role based authentication. If the user is admin he will be directed to admindashboard and user will be redirected to his respective dashboard where they share a common login portal.
If a person enters a url of the admin/user dashboard before login it asks the person to login but doesn't redirect to entered url. Instead throws an error "cannot call sendRedirect".
My code for security configuration file
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.web.util.UrlPathHelper;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired private LoginSuccessHandler loginSuccessHandler;
#Bean
AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider=new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(new BCryptPasswordEncoder());
return provider;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/userhome").hasAuthority("USER").
antMatchers("/adminhome").hasAuthority("ADMIN")
.antMatchers("/register").permitAll()
.and().formLogin().loginPage("/login")
.successHandler(loginSuccessHandler)
.permitAll().and().logout().logoutSuccessHandler(new LogoutSuccessHandler() {
#Override
public void onLogoutSuccess(HttpServletRequest request,HttpServletResponse response,Authentication authentication) throws IOException,ServletException{
System.out.println("The User "+authentication.getName() + " has logged out");
UrlPathHelper helper=new UrlPathHelper();
String context=helper.getContextPath(request);
response.sendRedirect(context+"/home");
}
}).permitAll();
http.csrf().disable();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
My Login Successful handler
package strictly.cinema.config;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import strictly.cinema.service.CustomUserDetails;
#Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities =userDetails.getAuthorities();
authorities.forEach(auth->System.out.println(auth.getAuthority()));
String redirectURL=request.getContextPath();
if(userDetails.hasRole("USER"))
redirectURL+="/userhome";
else if(userDetails.hasRole("ADMIN"))
redirectURL+="/adminhome";
response.sendRedirect(redirectURL);
super.onAuthenticationSuccess(request, response, authentication);
}
}
Overriden the logout handler in the security handler itself.
Need help to store the entered URL once the user is authenticated and eligible to access the URL he should be redirected to the URL after the login

Instead of using successHandler, you could redirect him to a success endpoint as follow :
.defaultSuccessUrl("/loginSuccess")
And the new endpoint will redirect him to "/userhome" or "/adminhome" based on his role.
(Below was not tested)
Success endpoint :
#GetMapping("/loginSuccess")
public void getLoginInfo(
#AuthenticationPrincipal UserDetails authentication,
HttpServletResponse response) throws IOException {
if (authentication.getAuthorities()
.contains(new SimpleGrantedAuthority("ADMIN"))) {
response.sendRedirect("/adminhome");
} else {
response.sendRedirect("/userhome");
}
}

Related

Register api is resposing 403 forbidden but csrf is disabled in spring boot

I am creating backend app and testing as well. my register url is resposing 403 forbidden but csrf is disabled. I can't fix this problem. Please help me P
Here is my configuration
package uz.renessans.configuration;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import uz.renessans.entity.user.UserRepository;
import uz.renessans.security.JwtFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final JwtFilter jwtFilter;
private final UserRepository userRepository;
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetailsService userDetailsService = username ->
userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username));
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
String[] OPEN_URLS = {
"/api/v1/register/**",
"/swagger-ui/**",
"/api/v1/login"
};
http
.csrf()
.disable()
.httpBasic()
.disable()
.authorizeRequests()
.antMatchers(
"/api/v1/register/**",
"/swagger-ui/**",
"/api/v1/login"
)
.permitAll()
.anyRequest()
.authenticated();
// .permitAll();
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Here is my jwt filter class:
package uz.renessans.security;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import uz.renessans.entity.user.User;
import uz.renessans.entity.user.UserRepository;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
#Component
#RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
private final JwtProvider jwtProvider;
private final UserRepository userRepository;
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.startsWith("Bearer") && authorization.length() > 7) {
authorization = authorization.substring(7);
String username = jwtProvider.getPhoneNumber(authorization);
if (username != null) {
Optional<User> optionalUser = userRepository.findByUsername(username);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = null;
if (optionalUser.isPresent()) {
usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(optionalUser.get(), null, optionalUser.get().getAuthorities());
}
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
filterChain.doFilter(request, response);
}
}
Here is my register api
public HttpEntity<?> register(RegisterDto dto, Role role) {
if (userRepository.existsByUsername(dto.getUsername()))
return new ResponseEntity<>(new ApiResponse("Username already exists", false), HttpStatus.CONFLICT);
if (!dto.getPassword().equals(dto.getRePassword()))
return new ResponseEntity<>(new ApiResponse("Password must match", false), HttpStatus.CONFLICT);
User user = new User();
user.setRole(role);
user.setUsername(dto.getUsername());
user.setPassword(passwordEncoder.encode(dto.getPassword()));
user.setFullName(dto.getFullName());
User savedUser = userRepository.save(user);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
savedUser.getUsername(), savedUser.getPassword());
authenticationManager.authenticate(authenticationToken);
String token = jwtProvider.generateToken(savedUser.getUsername(), savedUser.getRole());
Response response = Response.builder().token(token).role(role.toString()).build();
return new ResponseEntity<>(new ApiResponse("Registered Successfully", true, response), HttpStatus.OK);
}

Spring Security -The dependencies of some of the beans in the application context form a cycle

I got error while running this code, there is an injection cycle in the code but I cannot find it. btw, I'm new with Spring.
How can I solve this problem? And any good documentation about it ?
Here is my code;
WebSecurityConfiguration class:
package com.trendyol.app;
import com.trendyol.app.auth.JwtTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true) //Tüm methodlarımızdan önce security devreye girer
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
///////////////////
#Autowired
private JwtTokenFilter jwtTokenFilter;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configurePasswordEncoder(AuthenticationManagerBuilder builder ) throws Exception{
builder.userDetailsService(userDetailsService).passwordEncoder(getBCryptPasswordEncoder());
}
///////////////////
#Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager getAuthenticationManager() throws Exception{
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login") //bu adress hariç
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
UserDetailsService:
package com.trendyol.app.auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
#Service
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
private Map<String,String > users=new HashMap<>();
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#PostConstruct
public void init(){
users.put("temelt", passwordEncoder.encode("123"));
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(users.containsKey(username)){
return new User(username,users.get(username),new ArrayList<>());
}
throw new UsernameNotFoundException(username);
}
}
LOGs:
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| webSecurityConfiguration (field private org.springframework.security.core.userdetails.UserDetailsService com.trendyol.app.WebSecurityConfiguration.userDetailsService)
↑ ↓
| userDetailsService (field private org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder com.trendyol.app.auth.UserDetailsService.passwordEncoder)
└─────┘

Spring Basic Auth not working using BCrypt Encoding - I am getting redirected to login popup again even after entering correct credentials

Below is my PasswordEncoder Class
package com.example.springsecuritybasic.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
public class PasswordConfig {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Below is my ApplicationSecurityConfig Class
package com.example.springsecuritybasic.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter{
private final PasswordEncoder passwordEncoder;
#Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","index","/css/*","/js/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Override
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}
}
Below is my Main Class -
package com.example.springsecuritybasic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringsecuritybasicApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritybasicApplication.class, args);
}
}
From the WebSecurityConfigurerAdapter#userDetailsService Javadoc:
Allows modifying and accessing the UserDetailsService from userDetailsServiceBean() without interacting with the ApplicationContext. Developers should override this method when changing the instance of userDetailsServiceBean().
To configure a custom user, you can register a UserDetailsService bean rather than overriding the method
#Bean
protected UserDetailsService userDetailsService() {
UserDetails annasmithUser = User.builder()
.username("anna")
.password(this.passwordEncoder.encode("password"))
.roles("STUDENT")
.build();
return new InMemoryUserDetailsManager(
annasmithUser
);
}

Getting problem authenticationProvider in jwt authorization

I am getting error in configure method of SecurityConfig class whose code is here:
package com.sumit.Security;
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.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.sumit.Repo.UserRepository;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
private UserRepository userRepository;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// remove csrf and state in session because in jwt we do not need them
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager(),userRepository))
.authorizeRequests()
// configure access rules
.antMatchers("/register").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN","USER")
.antMatchers("/management").hasAnyRole("MANAGER","ADMIN")
.antMatchers("/page1").hasAnyAuthority("ROLE_ADMIN","ACCESS_PAGE1")
.antMatchers("/page2").hasAnyAuthority("ROLE_ADMIN","ACCESS_PAGE2")
.anyRequest().authenticated();
// .and()
// .formLogin()
// .loginPage("/login")
// .usernameParameter("username")
// .passwordParameter("password").successForwardUrl("/welcome")
// .permitAll();
}
#Bean
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(this.userDetailsService);
return daoAuthenticationProvider;
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
in above code, error lies here auth.authenticationProvider(authenticationProvider());
code is getting compiled fine but due to this i am getting 403 forbidden. Flow is getting broken here
JwtAutheticationFilter class is here
package com.sumit.Security;
import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sumit.Repo.UserRepository;
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
LoginModel credentials = null;
try {
credentials = new ObjectMapper().readValue(request.getInputStream(), LoginModel.class);
} catch (Exception e) {
e.printStackTrace();
}
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
credentials.getUsername(), credentials.getPassword(), new ArrayList<>());
Authentication auth = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
return auth;
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
UserPrincipal principal = (UserPrincipal) authResult.getPrincipal();
String token = JWT.create()
.withSubject(principal.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + JWTProperties.EXPIRATION_TIME))
.sign(HMAC512(JWTProperties.SECRET.getBytes()));
response.addHeader(JWTProperties.HEADER_STRING, JWTProperties.TOKEN_PREFIX + token);
}
}
JwtAuthorizationFilter class is here
package com.sumit.Security;
import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import com.auth0.jwt.JWT;
import com.sumit.Repo.UserRepository;
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
#Autowired
private UserRepository userRepository;
public JwtAuthorizationFilter(AuthenticationManager authenticationManager,UserRepository userRepository
) {
super(authenticationManager);
}
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// Read the Authorization header, where the JWT token should be
String header = request.getHeader(JWTProperties.HEADER_STRING);
// If header does not contain BEARER or is null delegate to Spring impl and exit
if (header == null || !header.startsWith(JWTProperties.TOKEN_PREFIX)) {
chain.doFilter(request, response);
return;
}
// If header is present, try grab user principal from database and perform authorization
Authentication authentication = getUsernamePasswordAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
// Continue filter execution
chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request) {
String token = request.getHeader(JWTProperties.HEADER_STRING)
.replace(JWTProperties.TOKEN_PREFIX,"");
if (token != null) {
// parse the token
String userName = JWT.require(HMAC512(JWTProperties.SECRET.getBytes()))
.build()
.verify(token)
.getSubject();
if (userName != null) {
User user = userRepository.findByUsername(userName);
UserPrincipal principal = new UserPrincipal(user);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userName, null, principal.getAuthorities());
return auth;
}
return null;
}
return null;
}
}
User registration process is working fine but authentication is not working because of above mentioned code.
I am using postman to verify it.
Don't know what trouble i am facing and totally frustrated.

"could not obtain access token" error in spring security oauth2

In my spring project i have an oauth2 client app running on localhost:9999 and an oauth2 authorization server running on localhost:8080.
In result, after approval page, i see error page that i don't know what is the problem?
when press F12 i see that set-cookie done! but /oauth/token not called! and /me also not called! and browser not redirect to localhost:9999.
my client app
package sso.client;
import java.security.Principal;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#EnableAutoConfiguration
#Configuration
#EnableOAuth2Sso
#RestController
public class App {
#RequestMapping("/")
public String home(Principal user) {
return "Hello " + user.getName();
}
public static void main(String[] args) {
new SpringApplicationBuilder(App.class)
.properties("spring.config.name=client").run(args);
}
}
client.yml
server:
port: 9999
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
my authorization server
package sso.raymon;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.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.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#Configuration
#EnableAutoConfiguration
#RestController
#EnableWebSecurity
public class App extends WebSecurityConfigurerAdapter
{
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
#Configuration
#EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter{
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
// TODO Auto-generated method stub
security.allowFormAuthenticationForClients();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// #formatter:off
clients.inMemory()
.withClient("acme")
.authorizedGrantTypes("authorization_code")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.secret("acmesecret");
// #formatter:on
}
}
#RequestMapping("/me")
public String home(Principal user) {
return user.getName();
}
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/me")
.authorizeRequests().anyRequest().authenticated();
}
}
}
application.properties
security.user.name=forough
security.user.password=m123
Error in blow URL:
localhost:9999/login?code=xZgYwZ&state=27XzVY
Error:
Whitelable Error Page
this application has no explicit mapping for /error, so you are seeing this a fallback.
There was an unexpected erroe (type=Unauthorized, atatus=401).
Authentication Failed: could not obtain access token

Resources