Spring security Role based HTTP request Authorization - java

I am getting 403 forbidden on Deleting an item from the inventory as well as creating a new resource in the database and below is my configuration and the controller written by me.
WebSecurityConfiguration Class:
package com.inventoryservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
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.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test")
.password("test_pass")
.roles("ADMIN")
.and()
.withUser("store")
.password("store_pass")
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.antMatchers(HttpMethod.DELETE, "/items-management").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/items-management").hasAnyRole("ADMIN","USER")
.antMatchers(HttpMethod.GET, "/items-management").permitAll()
.anyRequest().authenticated();
}
#Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Inventory controller:
It has all the endpoints being configured with the database records fetching from the services
package com.inventoryservice.controller;
import com.inventoryservice.dto.request.InventoryRequestDto;
import com.inventoryservice.dto.response.InventoryItemDto;
import com.inventoryservice.dto.response.InventoryResponseDto;
import com.inventoryservice.entity.Inventory;
import com.inventoryservice.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping("/items-management")
public class InventoryController {
private ItemService itemService;
#Autowired
public InventoryController(ItemService itemService) {
this.itemService = itemService;
}
#GetMapping
public ResponseEntity<InventoryResponseDto> getItems() {
return new ResponseEntity(
InventoryResponseDto.builder()
.lines(itemService.getItems())
.build()
, HttpStatus.OK
);
}
#PostMapping
public ResponseEntity<InventoryResponseDto> create(#RequestBody InventoryRequestDto inventory) {
return new ResponseEntity(
InventoryResponseDto
.builder()
.lines(itemService.create(inventory.getLines()))
.build()
, HttpStatus.CREATED
);
}
#DeleteMapping
public ResponseEntity delete(#RequestBody InventoryItemDto inventoryItemDto) {
itemService.deleteItems(
inventoryItemDto.getItemIds()
);
return ResponseEntity.ok(inventoryItemDto);
}
}

You've encountered this issue because in Spring Security protection against Cross-Site Request Forgery (CSRF) attack, which aims to trick the user to execute certain action in the application where they are authenticated, is enabled by default.
CSRF protection is meant to guard against undesirable mutating actions, therefore your POST-request fails. For more information on CSRF and when it's justifiable to disable CSRF protection, refer to the documentation.
For now, just in order to test your end-points, you can disable CSRF like that:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.antMatchers(HttpMethod.DELETE, "/items-management").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/items-management").hasAnyRole("ADMIN","USER")
.antMatchers(HttpMethod.GET, "/items-management").permitAll()
.anyRequest().authenticated()
.csrf().disable(); // <- add this line
}

Related

Getting org.springframework.security.access.AccessDeniedException: Access Denied Even After data saved to database in jwtAuthentication

This is my controller class code which I am using for getting user and save that particular user in database but after hitting data/or sending the data it was committed to my database but after that I am getting this error message.
package com.app.Exam.USerController;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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 com.app.Exam.Models.Roles;
import com.app.Exam.Models.User;
import com.app.Exam.Models.UserRoll;
import com.app.Exam.Service.UserService;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
#RequestMapping("/user")
public class UserController {
#Autowired
private UserService userService;
#Autowired
private PasswordEncoder bCryptPasswordEncoder;
#PostMapping("/")
public User createUser(#RequestBody User user) throws Exception {
User user2=new User();
user2.setPassword(this.bCryptPasswordEncoder.encode(user.getPassword()));
user2.setEmail(user.getEmail());
user2.setFirstName(user.getFirstName());
user2.setLastName(user.getLastName());
user2.setPhone(user.getPhone());
user2.setUserName(user.getUserName());
Roles roll=new Roles();
//roll.setRollId(46L);
roll.setRollName("NORMAL");
//user.setUserRolls(list);
List<UserRoll> list=new ArrayList<>();
UserRoll userRoll=new UserRoll();
userRoll.setRoles(roll);
userRoll.setUser(user2);
list.add(userRoll);
roll.setUserRolls(list);
User local=this.userService.CreateUser(user2,list);
return local;
}
#GetMapping("/{username}")
private User getUserByName(#PathVariable("username") String username) {
User user=this.userService.getUserByName(username);
return user;
}
// #GetMapping("/{id}")
// private User deleteUser(#PathVariable("id") Long id) throws Exception {
// User user=this.userService.deleteUserbyid(id);
// return user;
// }
}
My spring security config class was as below:
package com.app.Exam.Security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.app.Exam.JwtConfig.JwtAuthenticationEntryPoint;
import com.app.Exam.JwtConfig.JwtRequestFilter;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
JwtRequestFilter jwtAuthenticationFilter;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
http
.csrf().disable().cors().disable()
.authorizeHttpRequests()
.requestMatchers("/Authenticate","/user/").permitAll()
.requestMatchers(HttpMethod.OPTIONS).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authenticationProvider(this.daoAuthenticationProvider());
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
// #Override
// protected void configure(HttpSecurity http) throws Exception {
// http
// .csrf().disable().cors()
// .disable().authorizeHttpRequests().antMatchers("/Authenticate","/user/").permitAll()
// .antMatchers(HttpMethod.OPTIONS).permitAll()
// .anyRequest().authenticated()
// .and()
// .exceptionHandling()
// .authenticationEntryPoint(jwtAuthenticationEntryPoint)
// .and()
// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//
// http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
// }
//
#Bean
PasswordEncoder pass() {
return new BCryptPasswordEncoder();
}
// #Bean
// AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
// return authenticationConfiguration.getAuthenticationManager();
// }
#Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Bean
DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider=new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(this.userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(this.pass());
return daoAuthenticationProvider;
}
}
My errors Stackstrace is as belows..
enter image description here
enter image description hereenter code here
enter image description here
After to many reaserch i found my answer this error happens because i am not providing the user roll from front end and defining it harrcoded in my backend
if we wanted to do that we have to specify that property in model with #JsonIgnore like bellow one
#OneToMany(cascade = CascadeType.ALL ,fetch = FetchType.EAGER,mappedBy ="user")
#JsonIgnore
private List userRolls=new ArrayList<>();
it informs the serverlet request to egnore the null json of that specific property......
For this kind of databind errors use #JsonIgnore it works for me. this is jaxb databind error thats why spring security throwing Access denied error After Commiting data to Db...

How to make Spring security to redirect user to the original requested page after successfully authenticated by the CAS server

I have a spring boot RESTFul web application, which uses CAS server for Enterprise Single Sign-On. If a user, who is not logged-in, tries to access a secure page, that user is redirected to the CAS server for authentication. On successful authentication, the user is redirected to the home page of spring boot RESTFul web application - not the secured page, the user tries to access. How can we directly redirect the user to the secure page, which the user wants to access after successful login?
The spring-security-cas-client is used to implement CAS authentication. An AuthenticationSuccessHandler is implemented to set UseReferer true. The spring security config class is as follows:
package com.example.app
import java.util.Arrays;
import org.jasig.cas.client.session.SingleSignOutFilter;
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.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private AuthenticationProvider authenticationProvider;
private AuthenticationEntryPoint authenticationEntryPoint;
private SingleSignOutFilter singleSignOutFilter;
private LogoutFilter logoutFilter;
#Autowired
public SecurityConfig(CasAuthenticationProvider casAuthenticationProvider,
AuthenticationEntryPoint
eP,
LogoutFilter lF
, SingleSignOutFilter ssF
) {
this.authenticationProvider = casAuthenticationProvider;
this.authenticationEntryPoint = eP;
this.logoutFilter = lF;
this.singleSignOutFilter = ssF;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**", "/path-1", "/path-2")
.authenticated()
.and()
.authorizeRequests()
.regexMatchers("/")
.permitAll()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.logout().logoutSuccessUrl("/logout")
.and()
.addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
.addFilterBefore(logoutFilter, LogoutFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(Arrays.asList(authenticationProvider));
}
#Bean
public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sP) throws Exception {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setServiceProperties(sP);
filter.setAuthenticationManager(authenticationManager());
return filter;
}
#Bean
public AuthenticationSuccessHandler successHandler() {
SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
handler.setUseReferer(true);
return handler;
}
}
Using of SavedRequestAwareAuthenticationSuccessHandler instead of SimpleUrlAuthenticationSuccessHandler might help you achieve the redirection.
#Bean
public AuthenticationSuccessHandler successHandler() {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setTargetUrlParameter("redirectTo");
handler.setDefaultTargetUrl("/");
return handler;
}

Spring boot OAuth2Client, user not authenticated after callback: SecurityContext is empty or contents are anonymous

I'm configuring a Spring Boot application that will authenticate the user using OAuth2 and OpenID Connect. For the implementation, I follow the reference here: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2
After the AuthorizationCode is done, the user is not authenticated. How do I authenticate the user ?
The OpenID server I rely on requires an extra parameter for the authorization endpoint (acr_values={value}).
I'm able to add the parameter using an AuthorizationRequestResolver and call the authorization endpoint, then the server redirects me on my callback but the user is not authenticated. From the trace, the SecurityContext is empty and not save in the httpsession.
I can see in the logs that the POST request to the token endpoint is sent and I get a response 200.
MySecurityConfig
test
package com.uta.security.edc.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import com.uta.security.edc.oauth2.MyAuthorizationRequestResolver;
import com.uta.security.edc.oauth2.MyTokenResponseConverter;
#Configuration
#EnableOAuth2Client
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ClientRegistrationRepository clientRegistrationRepository;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/connect/**", "/test/**", "/assets/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/connect/login")
.authorizationEndpoint()
.baseUri("/connect/authorization")
.authorizationRequestResolver(this.authorizationRequestResolver())
.and()
.redirectionEndpoint()
.baseUri("/connect/callback")
.and()
.tokenEndpoint()
.accessTokenResponseClient(this.accessTokenResponseClient())
.and()
.userInfoEndpoint()
.and()
.defaultSuccessUrl("/")
.failureUrl("/connect/loginFailure")
.and()
.oauth2Client();
}
#Bean
public MyAuthorizationRequestResolver authorizationRequestResolver()
{
return new MyAuthorizationRequestResolver(this.clientRegistrationRepository);
}
#Bean
public OAuth2RestTemplate oauth2RestTemplate()
{
return new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
}
#Bean
protected OAuth2ProtectedResourceDetails resource() {
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId("my-connect");
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
List<String> scopes = new ArrayList<String>(1);
scopes.add("uta-poc-edc");
resource.setAccessTokenUri(clientRegistration.getProviderDetails().getTokenUri());
resource.setClientId(clientRegistration.getClientId());
resource.setClientSecret(clientRegistration.getClientSecret());
resource.setScope(scopes);
return resource;
}
#Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient()
{
DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter = new OAuth2AccessTokenResponseHttpMessageConverter();
tokenResponseHttpMessageConverter.setTokenResponseConverter(new MyTokenResponseConverter());
RestTemplate restTemplate = this.oauth2RestTemplate();
//RestTemplate restTemplate = new RestTemplate(Arrays.asList(new FormHttpMessageConverter(), tokenResponseHttpMessageConverter));
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
accessTokenResponseClient.setRestOperations(restTemplate);
return accessTokenResponseClient;
}
/*#Bean
public OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository)
{
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}*/
}
and also MyClientApplication
package com.uta.security.edc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextListener;
#SpringBootApplication
public class myClientApplication extends SpringBootServletInitializer
{
public static void main(String[] args)
{
SpringApplication.run(myClientApplication.class, args);
}
#Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
}
I need the user to be authenticated and its authentication informations saved in its httpsession in order to request Resource servers.
Thank you for your help!

CORS blocked Angular 7 and Spring 5

I'm running a Spring 5 with Spring Security and Angular 7 project and trying to wire the frontend but keep getting this err message. I should note the projects are two different directories on my computer
OS backend > spring
OS frontend > angular
Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:4200'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
I've gone through a bunch of threads here on stackoverflow but none would help.
From what i've gathered the issue is my spring security config
SPRING SECURITY FILE
package com.starter_kit.auth;
import com.starter_kit.auth.Auth.CustomizeAuthenticationSuccessHandler;
import com.starter_kit.auth.Company.CompanyRepo;
import com.starter_kit.auth.Users.UserRepo;
import com.starter_kit.auth.Users.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
#Configuration
#EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
// code
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetailsService userDetailsService = mongoUserDetails();
auth
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/dashboard/").hasAuthority("ADMIN").anyRequest()
.authenticated().and().csrf().disable().formLogin().successHandler(customizeAuthenticationSuccessHandler)
.loginPage("/login").failureUrl("/login?error=true")
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("/**"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","DELETE","PUT"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Spring Controller
#RestController
#CrossOrigin(origins = "http://localhost:4200")
#RequestMapping("/")
public class LoginController {
#Autowired
private UserService userService;
#PostMapping(path = "/login", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public UserDetails login(#RequestBody User user) {
return userService.loadUserByUsername(user.getEmail());
}
}
and my ANGULAR TS HTTP CALL
private loginAuth: string = "http://localhost:8080/login";
public headers = new HttpHeaders({ "Access-Control-Allow-Credentials": "true" })
public loginUser(user: any) {
return this.http.post(
this.loginAuth,
user,
{ headers: this.headers }
);
}
any help would be great
Spring provides an out of the box solution to exclude OPTIONS requests from authorization checks
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().authorizeRequests() ...
}
The cors() method will add the Spring-provided CorsFilter to the application context which in turn bypasses the authorization checks for OPTIONS requests.

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed in spring security spring boot [duplicate]

This question already has answers here:
java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed
(9 answers)
Closed 4 years ago.
This is my security config in my springboot application
package com.logan.cricketbeting.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
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;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.logan.cricketbeting.Service.CustomUserDetailsService;
import com.logan.cricketbeting.Service.UserServiceImpl;
//security configuration class for implementing spring security on urls
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsService userDetailsService;
//for handling user success handler
#Autowired
private CustomizeAuthenticationSuccessHandler customizeAuthenticationSuccessHandler;
#Override
//this configuration is for handling user requests
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/orders").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/admin/**").hasAuthority("admin")
.antMatchers("/distributor/**").hasAuthority("distributor")
.antMatchers("/user/**").hasAuthority("user").anyRequest()
.authenticated().and().csrf().disable().formLogin().successHandler(customizeAuthenticationSuccessHandler)
.loginPage("/login").failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login").and().exceptionHandling().accessDeniedPage("/403");
}
//this method allows static resources to be neglected by spring security
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/assets/**","/fonts/**","/vendor/**");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//BCryptPasswordEncoder encoder = passwordEncoder();
//auth.inMemoryAuthentication().withUser("logan#yahoo.com").password(encoder.encode("admin")).roles("user");
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
And this is my customsuccess handler
package com.logan.cricketbeting.security;
import java.io.IOException;
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.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
/*
* This is an Authentication Success handler class for handling what happens after the user is suc
* successfully logined in the application
*
*
*
* */
#Component
public class CustomizeAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
//set our response to OK status
response.setStatus(HttpServletResponse.SC_OK);
//this check granted authorities against the username
for (GrantedAuthority auth : authentication.getAuthorities()) {
//if the granted authority is user then it is allowed
//if its admin it is allowed
if("admin".equals(auth.getAuthority())) {
response.sendRedirect("/admin/home"); //working fine
}
else if("distributor".equals(auth.getAuthority())) {
response.sendRedirect("/distributor/home");//working fine
}
else if ("user".equals(auth.getAuthority())) {
response.sendRedirect("/user/home");//it is not working
}
//else it redirects to the 403 forbidden error
else {
response.sendRedirect("/403");
}
}
}
}
My admin and distributor url is working fine after login but the user one gives an error
java.lang.IllegalStateException: Cannot call sendRedirect() after the
response has been committed
I dont where is the glitch ,any idea how to solve this???
if the user has multiple authorities your code code calls sendRedirect multiple times. Adding a break or return after each sendRedirect should solve the issue.

Categories