When I'm entering users/update/{id} with some id, for example id = 6, I'm getting "Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]".
Basically, what I aimed at was to when I'm going on that URL (users/update/{id}) is:
method updateUser() triggered by going on mentioned URL retrieves user with id = 6 from repository
build a viewModel from it user with id = 6
pass this viewModel to HTML template "registration-formUpdate" as a "user" object in <form class="form-horizontal" method="post" th:href="#{~/registration}" th:object="${user}">
which then passes this object to endpoint "/registration" and to "registrationUsersAdding()" method in RegistrationController class to automatically fill the form with values from the user retrieved from repository
by clicking "add" button on the "registration-formUpdate" template save the updated user to database
However, when I click the "add" buttton, I get the 405 status and "Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]"
Sorry if my explanation isn't all that good, I'm learning Spring and English isn't my first language. I've done this this way 3-4 times on different apps before and it always worked, in this same project I have Events class with different entities, but same logic and it works. I don't know why here it doesn't.
Controller class
#RequiredArgsConstructor
#Controller
public class RegistrationController {
private final UserService userService;
private final UserRepository userRepository;
#PostMapping("/registration")
public String registrationUsersAdding(#ModelAttribute("user") #Valid UserViewModel user2,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
if (user2.getId() == null) {
return "registration-form";
} else {
return "registration-formUpdate";
}
} else {
if (user2.getId() == null) {
userService.add(user2);
} else {
userService.update(user2);
}
}
return "redirect:/login";
}
#Secured("ROLE_ADMIN")
#GetMapping("users/update/{id}")//toooooooo
public String updateUser(#PathVariable(value = "id") Long id, Model model) {
var user = userService.userToViewModel(userRepository.getOne(id));
model.addAttribute("user", user);
return "registration-formUpdate";
}
}
Service class
#Service
#RequiredArgsConstructor
public class UserService implements AddUpdateGetDeleteUser {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
private final PasswordEncoder passwordEncoder;
public void add(UserViewModel userViewModel) {
List<Role> roles;
Role role = new Role();
role.setType(RoleType.valueOf(userViewModel.getRoles()));// pomyslec nad tym
roleRepository.save(role);
roles = Collections.singletonList(role);
User user1 = User.builder()
.firstName(userViewModel.getFirstName())
.lastName(userViewModel.getLastName())
.login(userViewModel.getLogin())
.password(passwordEncoder.encode(userViewModel.getPassword()))
.email(userViewModel.getEmail())
.roles(roles)
.build();
userRepository.save(user1);
}
public void update(UserViewModel userDto) {
Optional<User> optionalUser = userRepository.findById(userDto.getId());
if (optionalUser.isPresent()) {
User user = optionalUser.get();
user.setId(userDto.getId());
user.setFirstName(userDto.getFirstName());
user.setLastName(userDto.getLastName());
user.setRoles(Collections.singletonList(GetRole(userDto.getRoles())));
user.setLogin(userDto.getLogin());
user.setEmail(userDto.getEmail());
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
userRepository.save(user);
}
}
public UserViewModel userToViewModel(User user) {
return UserViewModel.builder()
.id(user.getId())
.firstName(user.getFirstName())
.lastName(user.getLastName())
.roles(user.getRoles().get(0).toString())
.login(user.getLogin())
.email(user.getEmail())
.password(passwordEncoder.encode(user.getPassword()))
.build();
}
private Role GetRole(String roleType) {
var role = new Role();
role.setType(RoleType.valueOf(roleType));
return role;
}
}
Log
2022-12-30 00:35:43.807 INFO 5804 --- [ main] Z.Z.ZadanieRekrutacyjneApplication : Started ZadanieRekrutacyjneApplication in 10.364 seconds (JVM running for 11.253)
2022-12-30 00:36:28.052 INFO 5804 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-12-30 00:36:28.052 INFO 5804 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-12-30 00:36:28.055 INFO 5804 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2022-12-30 00:36:28.527 WARN 5804 --- [nio-8080-exec-1] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [387] milliseconds.
2022-12-30 00:37:13.180 WARN 5804 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
2022-12-30 00:42:59.615 INFO 5804 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2022-12-30 00:42:59.621 INFO 5804 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-12-30 00:42:59.624 INFO 5804 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-12-30 00:42:59.646 INFO 5804 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
It's ok now, changed in update-form html template from class="form-horizontal" method="post" th:href="#{~/registration}" th:object="${user}"> to <form action="#" method="POST" th:action="#{~/registration}" th:object="${user}"> and it works
My Spring Boot application is returning a 403 status code (forbidden) when I call a GET request in my AdminControllor
I am trying to blacklist URLs which have "/admin/**" except for those users who have the authority "ADMIN" in my database.
I have disabled csrf which seems to be the most common issue for 403 forbidden.
The problem seems to relate (see debug logs) to this:
Failed to authorize filter invocation [GET /admin/allusers] with attributes [hasAuthority('ADMIN')]
Logs
2022-09-08 13:56:20.018 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /admin/allusers
2022-09-08 13:56:20.026 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-09-08 13:56:20.026 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-09-08 13:56:20.042 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /admin/allusers] with attributes [hasAuthority('ADMIN')]
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8080/admin/allusers to session
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /error
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-09-08 13:56:20.090 DEBUG 21328 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Secured GET /error
2022-09-08 13:56:20.190 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext
2022-09-08 13:56:20.198 DEBUG 21328 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext
My Security Config class
package com.example.spring_security.config;
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.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.mvcMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().permitAll();
return http.build();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
My UserDetails
package com.example.spring_security.security;
import com.example.spring_security.entities.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.stream.Collectors;
public class SecurityUser implements UserDetails {
private final User user;
public SecurityUser(User user){
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getAuthorities()
.stream()
.map(SecurityAuthority::new)
.collect(Collectors.toList());
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
My UserDetailsService
package com.example.spring_security.services;
import com.example.spring_security.repositories.UserRepository;
import com.example.spring_security.security.SecurityUser;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
#Service
public class JpaUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public JpaUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public UserDetails loadUserByUsername(String username) {
var u = userRepository.findUserByUsername(username);
return u.map(SecurityUser::new)
.orElseThrow(() -> new UsernameNotFoundException("Username not found " + username));
}
}
My GrantedAuthority
package com.example.spring_security.security;
import com.example.spring_security.entities.Authority;
import org.springframework.security.core.GrantedAuthority;
public class SecurityAuthority implements GrantedAuthority {
private final Authority authority;
public SecurityAuthority(Authority authority) {
this.authority = authority;
}
#Override
public String getAuthority() {
return authority.getName();
}
}
I managed to get this working by adding formLogin() in my security configuration class. If omitted from Spring Security then there is no configuration for the authentication filter. See here.
I am making a Web Application Server with Spring boot.
In the early days of development, I used the settings http.csrf().disable() and the web page worked well.
But errors have been occurring ONLY at host address page ever since the disable setting was erased. When I requested GET, it works totally fine, however, it doesn't work with POST, PUT, DELETE... When I test at my localhost, all requests works including those methods.
Already, I used csrf token header, hidden csrf inputs of forms, and beforeSend that set csrf header in ajax. I even changed the nginx setting (error_page 405 =200 $uri;), but it remains the same.
This is my environment.
jdk 11
spring 2.3.5
AWS EC2 - Amazon Linux 2 AMI
AWS RDS - PostgreSQL 13
AWS S3
Nginx 1.18.0
gradle 5.6.4
thymeleaf
Is there anyone who can help me, please?
My Github Repository Link
# aws server- nohup.out
[ec2-user#teamcoder-webservice ~]$ vim ~/app/step3/nohup.out
2020-12-01 23:24:18.953 INFO 3697 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#3ad85136, org.springframework.security.web.context.SecurityContextPersistenceFilter#2bc426f0, org.springframework.security.web.header.HeaderWriterFilter#176f7f3b, org.springframework.security.web.csrf.CsrfFilter#7d3c09ec, org.springframework.security.web.authentication.logout.LogoutFilter#1f53481b, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter#7f93dd4e, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter#5ad5be4a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#33425811, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#4cb2918c, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#737d100a, org.springframework.security.web.session.SessionManagementFilter#58740366, org.springframework.security.web.access.ExceptionTranslationFilter#4af45442, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#671c4166]
2020-12-01 23:24:20.068 INFO 3697 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-12-01 23:24:20.550 INFO 3697 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2020-12-01 23:24:20.552 INFO 3697 --- [ main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
2020-12-01 23:24:21.474 INFO 3697 --- [ main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-12-01 23:24:21.499 INFO 3697 --- [ main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-12-01 23:24:21.527 INFO 3697 --- [ main] c.j.team.teamcoder.TeamCoderApplication : Started TeamCoderApplication in 17.806 seconds (JVM running for 19.458)
2020-12-01 23:24:23.438 INFO 3697 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-12-01 23:24:23.443 INFO 3697 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-12-01 23:24:23.460 INFO 3697 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 17 ms
2020-12-02 03:05:22.223 WARN 3697 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
# /etc/nginx/nginx.conf
http {
...
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
include /etc/nginx/conf.d/service-url.inc;
location / {
limit_except GET POST PUT DELETE {
deny all;
}
proxy_pass $service_url;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
error_page 405 =200 $uri;
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
#after change upper configuration
[ec2-user#teamcoder-webservice nginx]$ sudo /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Plus, the following code is java spring boot code.
<!--ajax non-used request in "user_info.html"-->
<form th:action="#{'/api/v1/user/pic/' + ${user.id}}" method="post" enctype="multipart/form-data" name="pictureForm">
<table>
<tr><td><label th:for="picture">Profile Image</label></td>
<td><input type="file" id="picture" name="picture" accept="image/png, image/jpeg" /></td></tr>
<tr><td><img th:src="#{${user.picture}}" id="picture_img" alt="put your image"></td>
<td><input type="button" name="Upload" value="Upload" onclick="submit_file_form(document.forms['pictureForm'].picture, 'pictureForm');" class="btn btn-info"/></td></tr>
</table>
<input type="hidden" name="pastPath" id="pastPath" th:value="${user.picture}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
</form>
//ajax used request in "user_info.html" -> "userInfo.js"
...
const csrfToken = $('#_csrf').attr('content');
const csrfHeader = $('#_csrf_header').attr('content');
var user_info = {
init : function () {
var _this = this;
$('#btn-update').on('click', function () {
_this.update();
});
$('#btn-delete').on('click', function () {
_this.delete();
});
},
update : function () {
var data = {
name: $('#name').val(),
tags: commaToArray(convertTags($('#tags').val())),
email: $('#email').val(),
birth: $('#birth').val(),
education: $('#education').val().toUpperCase(),
location: $('#location').val()
};
var id = $('#id').val();
$.ajax({
type: 'PUT',
url: '/api/v1/user/'+id,
dataType: 'json',
contentType:'application/json; charset=utf-8',
data: JSON.stringify(data),
beforeSend: function (xhr){
xhr.setRequestHeader(csrfHeader, csrfToken);
}
}).done(function() {
alert('your information is modified');
window.location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
});
},
...
<!-- in html header -->
<meta id="_csrf" th:name="${_csrf.parameterName}" th:content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
#RequiredArgsConstructor
#RestController
public class UserApiController {
private final UserService userService;
private final RoleService roleService;
#PutMapping("/api/v1/user/{id}")
public Long update(#PathVariable String id,
#RequestBody UserUpdateRequestDto requestDto){
roleService.reloadRolesForAuthenticatedUser(Role.USER.getKey());
return userService.update(Long.valueOf(id), requestDto);
}
}
#RequiredArgsConstructor
#RestController
public class FileController {
private final UserService userService;]
private final S3Service s3Service;
#PostMapping("/api/v1/user/pic/{id}")
public String updateUserPic(#PathVariable String id,
#RequestParam("pastPath") String pastPath,
#RequestPart("picture") MultipartFile multipartFile) throws IOException {
String uploadDir = s3Service.upload(pastPath, multipartFile,"users/");
userService.updatePic(Long.valueOf(id), uploadDir);
return "You successfully uploaded " + uploadDir + "!";
}
}
//SecurityConfig.java
#Configuration
#RequiredArgsConstructor
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**", "/assets/img/**", "/lib/**", "/user-photos/**", "/group-files/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("/", "/logoption","/user/denied", "/search/**", "/privacy/rule","/profile").permitAll()
.antMatchers("/api/v1/user/**", "/api/v1/**").hasRole("GUEST")
.antMatchers("/api/v1/group/**", "/group/**", "/api/v1/participate/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.logout().logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.accessDeniedPage("/user/denied")
.and()
.oauth2Login()
.loginPage("/logoption")
.defaultSuccessUrl("/")
.userInfoEndpoint()// after oauth2 login
.userService(customOAuth2UserService);
}
//for Spring Security
#Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher());
}
}
Try adding these to your SecurityConfig :
http.cors().and()....
And CORS config:
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); // TODO: lock down before deploying
config.addAllowedHeader("*");
config.addExposedHeader(HttpHeaders.AUTHORIZATION);
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
I'm trying to build spring boot project.
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/INTERNET_BANKING?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=springuser
spring.datasource.password=password
my application.properties file have these settings
#Repository
public interface adminRepository extends CrudRepository<Admins, Long> {
#Query(value = "select A_PASSWD from ADMIN where A_ID=?1", nativeQuery = true)
String checkPasswordById(long id);
}
my repository class have this func.
#GetMapping("/logWithID")
public String returnHomePage(#RequestParam("ID") long id, #RequestParam("passwd") String passwd) {
if (admrepo.existsById(id)) {
System.out.println(admrepo.checkPasswordById(id));
if (admrepo.checkPasswordById(id) == passwd) {
return "admin";
}else{
return "login";
}
} else if (cstrepo.existsById(id)) {
if (cstrepo.checkPasswordById(id) == passwd) {
return "customer";
}else{
return "login";
}
}else{
return "login";
}
}
my controller class have this func.
#Entity
#Table(name = "ADMIN")
public class Admins {
my entity class
-2020-10-10 22:42:32.482 - INFO 8068 --- [nio-8100-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2020-10-10 22:42:32.482 - INFO 8068 --- [nio-8100-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
-2020-10-10 22:42:32.489 - INFO 8068 --- [nio-8100-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 7 ms
-2020-10-10 22:43:51.754 -DEBUG 8068 --- [nio-8100-exec-4] org.hibernate.SQL : select count(*) as col_0_0_ from admin admins0_ where admins0_.a_id=?
-Hibernate: select count(*) as col_0_0_ from admin admins0_ where admins0_.a_id=?
2020-10-10 22:43:52.085 -DEBUG 8068 --- [nio-8100-exec-4] org.hibernate.SQL : select A_PASSWD from ADMIN where A_ID=?
-Hibernate: select A_PASSWD from ADMIN where A_ID=?
2020-10-10 22:43:52.154 - WARN 8068 --- [nio-8100-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1146, SQLState: 42S02
-2020-10-10 22:43:52.154 -ERROR 8068 --- [nio-8100-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Table 'INTERNET_BANKING.ADMIN' doesn't exist
-2020-10-10 22:43:52.245 -ERROR 8068 --- [nio-8100-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
-
java.sql.SQLSyntaxErrorException: Table 'INTERNET_BANKING.ADMIN' doesn't exist
& I'm getting this error.
I dropped my tables & rebuilt them again but the error persist.
I'm trying to get some Role-based authorization working on spring, but I have trouble with 403 responses on POST\PUT\DELETE requests. I've been looking for solutions elsewhere but provided solutions with disabling csrf do not solve the issue.
This is my HTTP config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.PATCH, "/user/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.PUT, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.POST, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.DELETE,"/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin().permitAll()
.and()
.logout().permitAll();
}
When I debug my code, only GET requests make my program go through the UserDetails objects to provide the Roles collection (as defined below)
public class BrevisFitUser extends User implements UserDetails {
public BrevisFitUser(final User user) {
super(user);
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles()
.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName().toUpperCase()))
.collect(Collectors.toList());
}
On a PUT request for instance, this is the log I get:
2019-11-20 13:28:47.560 DEBUG 15456 --- [nio-8080-exec-5] o.a.coyote.http11.Http11InputBuffer : Received [PUT /exercise/strap/3 HTTP/1.1
Content-Type: application/json
Authorization: Basic c2ltb24ua25lejpzaW1vbi5rbmV6
User-Agent: PostmanRuntime/7.19.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 7a829877-6de4-4746-8e27-63677f0160d2
Host: localhost:8080
Accept-Encoding: gzip, deflate
Content-Length: 75
Cookie: JSESSIONID=45F53EE556C13E672E6ECFD5865B5FD6
Connection: keep-alive
{
"unitLength": 29,
"name": "Yellow strap home marked smaller"
}]
2019-11-20 13:28:47.560 DEBUG 15456 --- [nio-8080-exec-5] o.a.t.util.http.Rfc6265CookieProcessor : Cookies: Parsing b[]: JSESSIONID=45F53EE556C13E672E6ECFD5865B5FD6
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] o.a.catalina.connector.CoyoteAdapter : Requested cookie session id is 45F53EE556C13E672E6ECFD5865B5FD6
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] o.a.c.authenticator.AuthenticatorBase : Security checking request PUT /exercise/strap/3
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] org.apache.catalina.realm.RealmBase : No applicable constraints defined
2019-11-20 13:28:47.562 DEBUG 15456 --- [nio-8080-exec-5] o.a.c.authenticator.AuthenticatorBase : Not subject to any constraint
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#e2265dfb: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#e2265dfb: Principal: com.brevisfit.api.model.user.User[ iduser=1 ]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 45F53EE556C13E672E6ECFD5865B5FD6; Granted Authorities: ROLE_ADMIN, ROLE_TRAINER'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 4 of 15 in additional filter chain; firing Filter: 'CsrfFilter'
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/exercise/strap/3
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#25ff6f87
2019-11-20 13:28:47.565 DEBUG 15456 --- [nio-8080-exec-5] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Based on the issue with the csrf, I have added the following code to the configuration:
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
And have tried with removal of antMatchers and just require authenticationi:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
}
Any idea, why such behaviour?