Spring Security returns 403 on any request - spring

I created two users with ADMIN and USER roles, but every time I try to login server return 403.
WebSecurityConfig:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasAnyAuthority('ADMIN','USER')")
.and().formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout")
.and().csrf().disable();
}
my UserService which maps my users from db:
#Transactional(readOnly = true)
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUserName(username);
org.springframework.security.core.userdetails.User.UserBuilder builder = null;
if (user != null) {
builder = org.springframework.security.core.userdetails.User.withUsername(username);
builder.disabled(!user.isEnabled());
builder.password(user.getPassword());
String[] authorities = user.getUserRole()
.stream().map(a -> a.getRole()).toArray(String[]::new);
builder.authorities(authorities);
} else {
throw new UsernameNotFoundException("User not found.");
}
return builder.build();
}
csrf is disabled. I also use hasAnyUthority* method so I don't need ROLE_ prefix.
I use spring security 5
My login.html
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="resources/style.css"/>
</head>
<body>
<div class="container">
<header>
<h1>Login</h1>
</header>
<div class="alert alert-error" th:if="${error != null}">
<div>
<strong>Okay, Houston, we've had a problem here.</strong>
</div>
</div>
<div class="alert alert-error" th:if="${logout != null}">
<div>
<strong>Okay, Houston, you're logged out successfully .</strong>
</div>
</div>
<form class="form-horizontal" th:action="#{/login}" method="POST">
<fieldset>
<div class="control-group">
<label class="control-label">Login</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on">#</span>
<input id="loginField" name="username" class="span3" type="text"/>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">Password</label>
<div class="controls">
<input id="passwordField" name="password" class="span3" type="password"/>
</div>
</div>
<div class="form-actions">
<button id="loginButton" class="btn btn-primary" type="submit">Login</button>
</div>
</fieldset>
</form>
</div>
</body>
I did everything as in example projects but it still doesn't want to log me in.

I don't see that hasAnyAuthority(...) will work without "ROLE_", try .access("hasAnyRole('ADMIN','USER')") or .access("hasAnyRole('ROLE_ADMIN','ROLE_USER')").
Note that in String[] authorities = user.getUserRole().stream().map(a -> a.getRole()).toArray(String[]::new); you need in a.getRole() return with prefix ROLE_ or the same what you will have in hasAnyAuthority(...)
For example if your a.getRole() will return WHAT_EVER than hasAnyAuthority('WHAT_EVER) should work, but hasAnyRole('WHAT_EVER') will expect that a.getRole() returns ROLE_WHAT_EVER

Maybe it will help someone so i will unswer my question.
I couldn't login becouse when i launch my program, i add some new users with not encrypted password. But spring security decrypts it anyways so that is why i couldn't login and got 403 repsonse. All i needed is to encrypt password before adding it into database.

Related

View and controller data exchange

I'm using form tag to get information of title and content.
But I can't get any information from form tag.
It happens to me several time. I don't know what is the problem..
this is the controller code
#Slf4j
#Controller
#RequiredArgsConstructor
public class PostController {
private final PostRepository postRepository;
private final MemberService memberService;
#GetMapping("/board/upload")
public String moveToUploadPage(Model model) {
model.addAttribute("uploadPostForm", new UploadPostForm());
return "board/uploadForm";
}
#PostMapping("/board/upload")
public String updateBoard(#ModelAttribute UploadPostForm uploadPostForm, Authentication authentication, Model model) {
log.info("uploadPostForm.title = {}", uploadPostForm.getTitle());
Member member = findMember(authentication);
Post post = new Post(member, uploadPostForm.getTitle(), uploadPostForm.getContent());
postRepository.save(post);
return "/board/board";
}
}
this is html code
<!DOCTYPE html>
<html lang="kr" xmlns:th="http://www.thymeleaf.org">
<head th:insert="~{fragment/header :: header}">
<meta charset="utf-8">
</head>
<body>
<div th:replace="~{fragment/navbar :: nav}"></div>
<!-- Form Tag -->
<form th:action th:object="${uploadPostForm}" method="post" class="container-md">
<div class="m-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" th:field="*{title}">
</div>
<div class="m-3">
<label for="content" class="form-label">Text Area</label>
<textarea class="form-control" id="content" rows="10" th:field="*{content}"></textarea>
</div>
<div class="container" style="text-align: right">
<span class="m-3" th:text="|writer: | + ${#authentication.getName()}"></span>
<button type="submit" class="btn btn-primary">upload</button>
</div>
</form>
</body>

Springboot authentication issue

I have a spring boot application with spring security configured. I have redirected the login request to http://localhost:8000 where I'm running my front-end on a python server. Now when I try to post the login to my springboot application, it doesn't work. Even when I try from my postman, it says 405 error. How can I get this working. It works from /login if I put it as html in the same project but not from the python server or postman. What is the difference.
"message": "Request method 'POST' not supported",
"path": "/login"
Form Data
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<!-- Add page specific code/html START -->
<div class="container">
<h1 th:text="#{welcome.message}"></h1>
<form class="form-signin" name="loginForm" th:action="#{/login}" action="/login" method="POST">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="username" class="sr-only">Email address</label>
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
<label for="password" class="sr-only">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password" required="required" />
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
HTML code hosted on photon server
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Assessment App</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/main.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="panel panel-default main-header">
<div class="panel-body">
<div class ="pull-left">Assessments</div>
</div>
</div>
<div class="row">
<div class="login-container col-md-4 col-md-offset-4 col-sm-10 col-sm-offset-1 col-xs-12 col-xs-offset-0">
<div class="panel panel-login">
<div class="panel-heading">
<div class="panel-title">Sign In</div>
</div>
<div class="panel-body">
<form id="loginform" class="form-horizontal" role="form">
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="login-username" type="text" class="form-control" name="username" value="" placeholder="Username">
</div>
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="login-password" type="password" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<div class="col-sm-12 controls">
<input class="btn btn-primary" type="submit" value="Login">
</div>
</div>
</form>
<div class="login-form-error-text hidden">Invalid credentials</div>
</div>
</div>
</div>
</div>
</div>
<script src="../javascript/jquery-3.3.1.min.js"></script>
<script src ="../javascript/bootstrap.min.js"></script>
<script src="../javascript/lodash.min.js"></script>
<script src="../javascript/login.js"></script>
</body>
</html>
Corresponding js
$(document).ready(function () {
$('#loginform').submit(function (event) {
event.preventDefault();
$.ajax({
url : 'http://localhost:8080/j_spring_security_check',
type : 'POST',
contentType : 'application/json',
data : JSON.stringify({ j_username : $('#login-username').val(), j_password : $('#login-password').val() }),
success : function () {
window.location.href = '../html/assessment.html';
},
error : function () {
event.preventDefault();
alert('failed');
}
});
});
$('.form-tab-header').on('click', function () {
$('.login-form-error-text').addClass('hidden');
$('.form-tab-header').removeClass('active');
$(this).addClass('active');
$('.form-horizontal').addClass('hidden');
$('.' + $(this).attr('id') + '-content').removeClass('hidden');
});
});
Security Config
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${ldap.urls}")
private String ldapUrls;
#Value("${ldap.base.dn}")
private String ldapBaseDn;
#Value("${ldap.user.dn.pattern}")
private String ldapUserDnPattern;
#Value("${ldap.enabled}")
private String ldapEnabled;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.antMatchers("/assessments/**").fullyAuthenticated()
.antMatchers("/").permitAll()
.and()
.formLogin()
//.loginPage("http://htmlcode.s3-website.us-east-2.amazonaws.com")
.loginPage("http://localhost:8000")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("j_username")
.passwordParameter("j_password")
//.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
#Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/register");
// .antMatchers("/assessments/**");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if(Boolean.parseBoolean(ldapEnabled)) {
auth.ldapAuthentication()
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns(ldapUserDnPattern)
.contextSource()
.url(ldapUrls+ldapBaseDn);
}
}
#Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new LdapUserDetailsMapper() {
#Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
UserDetails details = super.mapUserFromContext(ctx, username, authorities);
return details;
}
};
}
#Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
}
You have forgotten to include csrf values.this is a security precaution mechanism to prevent cross site attacks. your have two options as a workaround :
1.Disabling CSRF:
as csrf is enabled by default, both POSTs and PUT Http methods are not allowed with CSRF enabled.
for disabling it you should add this to your security config
.csrf().disable()
for example you could have such thing:
http.
.csrf().disable().
authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
2.Send csrf token values :
If you are using login page with login form, we need to always include the CSRF token in the login form as a hidden parameter manually in the code:
<input
type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
if you want to login by ajax you should also include these two parameters included:
first hold the values in some variables:
<script type="text/javascript">
var csrfParameter = '${_csrf.parameterName}';
var csrfToken = '${_csrf.token}';
</script>
then include those into
var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
// include other values pass ,user, etc.
$.ajax({
type: 'POST',
cache: false,
url: /login,
data: jsonParams,
dataType = 'json',
contentType = 'application/json',
...
});
More Information
https://www.baeldung.com/spring-security-csrf
Ajax POST results in a 405 (Method Not Allowed) - Spring MVC
https://matthewbusche.com/2016/08/06/using-csrf-with-spring-security-and-ajax-calls/
Spring Security - 405 Request Method 'POST' Not Supported
HTTP 405 Not Allowed - Spring Boot + Spring Security
405 Method Not Allowed for POST
Spring Boot + Security + Thymeleaf and CSRF token not injected automatically

Springboot authentication issue with customer login

I have a spring boot application with spring security configured. I have redirected the login request to http://localhost:8000 where I'm running my front-end on a python server. Now when I try to post the login to my springboot application, it doesn't work. I looked into some posts online and changed the login path to /j_spring_security_check but it doesn't even seem to be trying to login as I don't see any logs in the console. Its taking me to login?error .Are there any other places where I can check the logs. Can I debug this somehow from some springboot classes.
Form Data
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<!-- Add page specific code/html START -->
<div class="container">
<h1 th:text="#{welcome.message}"></h1>
<form class="form-signin" name="loginForm" th:action="#{/login}" action="/login" method="POST">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="username" class="sr-only">Email address</label>
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
<label for="password" class="sr-only">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password" required="required" />
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
HTML code hosted on photon server
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Assessment App</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/main.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="panel panel-default main-header">
<div class="panel-body">
<div class ="pull-left">Assessments</div>
</div>
</div>
<div class="row">
<div class="login-container col-md-4 col-md-offset-4 col-sm-10 col-sm-offset-1 col-xs-12 col-xs-offset-0">
<div class="panel panel-login">
<div class="panel-heading">
<div class="panel-title">Sign In</div>
</div>
<div class="panel-body">
<form id="loginform" class="form-horizontal" role="form">
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="login-username" type="text" class="form-control" name="username" value="" placeholder="Username">
</div>
<div class="input-group assessment-input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="login-password" type="password" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<div class="col-sm-12 controls">
<input class="btn btn-primary" type="submit" value="Login">
</div>
</div>
</form>
<div class="login-form-error-text hidden">Invalid credentials</div>
</div>
</div>
</div>
</div>
</div>
<script src="../javascript/jquery-3.3.1.min.js"></script>
<script src ="../javascript/bootstrap.min.js"></script>
<script src="../javascript/lodash.min.js"></script>
<script src="../javascript/login.js"></script>
</body>
</html>
Corresponding js
$(document).ready(function () {
$('#loginform').submit(function (event) {
event.preventDefault();
$.ajax({
url : 'http://localhost:8080/j_spring_security_check',
type : 'POST',
contentType : 'application/json',
data : JSON.stringify({ j_username : $('#login-username').val(), j_password : $('#login-password').val() }),
success : function () {
window.location.href = '../html/assessment.html';
},
error : function () {
event.preventDefault();
alert('failed');
}
});
});
$('.form-tab-header').on('click', function () {
$('.login-form-error-text').addClass('hidden');
$('.form-tab-header').removeClass('active');
$(this).addClass('active');
$('.form-horizontal').addClass('hidden');
$('.' + $(this).attr('id') + '-content').removeClass('hidden');
});
});
Security Config
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${ldap.urls}")
private String ldapUrls;
#Value("${ldap.base.dn}")
private String ldapBaseDn;
#Value("${ldap.user.dn.pattern}")
private String ldapUserDnPattern;
#Value("${ldap.enabled}")
private String ldapEnabled;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.antMatchers("/assessments/**").fullyAuthenticated()
.antMatchers("/").permitAll()
.and()
.formLogin()
//.loginPage("http://htmlcode.s3-website.us-east-2.amazonaws.com")
.loginPage("http://localhost:8000")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("j_username")
.passwordParameter("j_password")
//.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
#Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/register");
// .antMatchers("/assessments/**");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if(Boolean.parseBoolean(ldapEnabled)) {
auth.ldapAuthentication()
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns(ldapUserDnPattern)
.contextSource()
.url(ldapUrls+ldapBaseDn);
}
}
#Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new LdapUserDetailsMapper() {
#Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
UserDetails details = super.mapUserFromContext(ctx, username, authorities);
return details;
}
};
}
#Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
}
I was finally able to fix this by removing JSON.stringfy in my post body of ajax request and setting the content type to application/x-www-form-urlencoded.

Spring Security doesn't post to provided login processing url

For some weird reason, I cannot hit the controller that is registered to handle login posts. I just get redirected to this silly image that is in my resources folder:
https://localhost:8443/images/piggy-bank.jpeg
Here is my controller.
#RequestMapping(value = "/login/process", method = RequestMethod.POST)
public String loginPost(HttpSession session, Authentication authentication) {
String client_id = (String) session.getAttribute("client_id");
if (client_id.equals(Constants.TRUSTED_CLIENT)) {
//TODO:
/*
* 1. Generate an access_token
* 2. Save to database
* 3. Form redirect url with all necessary tokens
* 4. Return redirect url string
*/
return "redirect:" + Constants.REDIRECT_TRUSTED_CLIENT;
}
long userId = AuthenticationUtils.getAuthenticatedUserId(authentication);
return "/user/" + userId;
}
Here is my security configuration:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("customUserDetailsService")
UserDetailsService userDetailsService;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/","/sign_up","/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.loginPage("/login")
.loginProcessingUrl("/login/process")
.defaultSuccessUrl("/")
.failureUrl("/access_denied")
.and()
.csrf()
.and()
.exceptionHandling()
.accessDeniedPage("/access_denied")
.and()
.logout()
.permitAll();
}
}
And here's the view:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<title>Spring App</title>
<!--/*/ <th:block th:include="fragments/headerinc :: head"></th:block> /*/-->
</head>
<body>
<div class="container">
<!--/*/ <th:block th:include="fragments/header :: header"></th:block> /*/-->
<div id="mainWrapper">
<div class="login-container">
<div class="login-card">
<div class="login-form">
<form th:action="#{/login/process}" method="post" class="form-horizontal">
<div th:if="${param.error != null}">
<div class="alert alert-danger">
<p>Invalid username and password.</p>
</div>
</div>
<div th:if="${param.logout != null}">
<div class="alert alert-success">
<p>You have been logged out successfully.</p>
</div>
</div>
<div class="input-group input-sm">
<label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
<input type="text" class="form-control" id="username" name="username" placeholder="Enter Username" />
</div>
<div class="input-group input-sm">
<label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" />
</div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<div class="form-actions">
<input type="submit"
class="btn btn-block btn-primary btn-default" value="Log in"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Inspecting my network data, I see that the form post to /login/process was successful and the server responded fine!
Request URL:https://localhost:8443/login/process
Request Method:POST
Status Code:302 Found
Remote Address:[::1]:8443
The log during spring startup also affirms the registration of url "/login/post" to the aforementioned controller. Corresponding log:
2016-04-21 20:44:30.725 INFO 25290 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login/process],methods=[POST]}" onto public java.lang.String com.springapp.controllers.UserController.loginPost(javax.servlet.http.HttpSession,org.springframework.security.core.Authentication)
The situation may be something more insidious, because I can't seem to be redirected to even the defaultSuccessURL page, i.e. the index ("/"). The same is the case (i.e. loginProcessingURL and defaultSuccessfulURL not redirecting) exists even if I use the default out-of-box login view. Is there something wrong with my jsp view? Am I missing some security configuration?
However, manually entering /user/{id} OR any other url successfully lands me to the target url as long as I'm properly authenticated. What does that mean?
Finally here is the 'header.html' and 'headerinc.html' thymeleaf fragments which are inserted in all my jsp:
header.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<link href="../../static/css/app.css"
th:href="#{css/app.css}" rel="stylesheet" media="screen"/>
<link href="../../static/css/bootstrap.css"
th:href="#{css/bootstrap.css}" rel="stylesheet" media="screen"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css"
th:href="#{/webjars/font-awesome/4.2.0/font-awesome.css}" rel="stylesheet" media="screen"/>
</head>
<body>
<div class="container">
<div th:fragment="header">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#" th:href="#{/}">Home</a>
<ul class="nav navbar-nav">
<!-- if logged in, then display -logout, else display -login, -Sign up. -->
<div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}">
<div th:if="${currentUser != null}">
<form th:action="#{/logout}" method="post">
<input type="submit" value="Log out"/>
</form>
</div>
<div th:if="${currentUser == null}">
<li>Log in</li>
<li>Sign up</li>
</div>
<!-- This is to simply test some authentication logic-->
All Users
</div>
</ul>
</div>
</div>
</nav>
<div class="jumbotron">
<div class="row text-center">
<div class="">
<h2>Spring Framework Example..</h2>
<h3>Spring Boot Web App</h3>
</div>
</div>
<div class="row text-center">
<img src="../../static/images/NewBannerBOOTS_2.png" width="400"
th:src="#{/images/piggy-bank.jpeg}"/>
</div>
</div>
</div>
</div>
</body>
</html>
headerinc.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en" th:fragment="head">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" media="screen" />
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="../static/css/guru.css"
th:href="#{/css/guru.css}" rel="stylesheet" media="screen"/>
</head>
<body>
</body>
</html>
This line:
.loginProcessingUrl("/login/process")
tells Spring Security to process the submitted credentials when sent the specified path and, by default, redirect user back to the page user came from. It will not pass the request to Spring MVC and your controller.
Maybe what you want instead of a request mapping is a custom AuthenticationSuccessHandler.
I had also the same issue very recently.
In my case, I had to add this code
<public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**","/assets/**", "/css/**");
}
Note:
Be careful not to use .anyRequest() here, like in
web.ignoring().antMatchers("/js/**","/assets/**", "/css/**").anyRequest()
Because that also gave me a lot of problems ...

Spring ModelAttribute nullPointerException

these are my controllers:
#RequestMapping(value="/requestBooking", method = RequestMethod.GET)
#ModelAttribute("booking")
public ModelAndView requestBooking(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ModelAndView view = new ModelAndView("requestBooking");
OAuthAuthenticationToken token = (OAuthAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if(token.getUserProfile().getAttributes().get("email").toString().matches(".*#nisum.com")==false){
SecurityContextHolder.clearContext();
return new ModelAndView("redirect:/j_spring_security_logout?redirectTo=/rejected");
}
VacationBooking booking=new VacationBooking();
String email=token.getUserProfile().getAttributes().get("email").toString();
User user=userImp.getUserByMail(email);
booking.setUser(user); //setting user
System.out.println(booking.getBookingId() + " - " + booking.getUser().getUserId());
view.addObject("booking", booking);
view.addObject("user", token.getUserProfile().getAttributes().get("email"));
return view;
}
#RequestMapping(value="/requestBooking/process", method=RequestMethod.POST)
public ModelAndView addBooking(#ModelAttribute("booking") VacationBooking booking , BindingResult result) {
/* val.validate(booking, result);*/
/* if(result.hasErrors()){
System.out.println("Error!!!!");
ModelAndView modelAndView = new ModelAndView("requestBooking");
return modelAndView;
}else{ */
SimpleMailMessage email2 = new SimpleMailMessage();
SimpleMailMessage emailPm = new SimpleMailMessage();
emailPm.setTo(booking.getUser().getMail()); //error here null value
email2.setTo(booking.getUser().getManager().getMail()); //error here, null value
email2.setSubject("Vacation Request");
emailPm.setSubject("Vacation Request");
emailPm.setText("<h3>Vacation Request<h3>\nThe employee has requested Vacation days between for leave. \n \n Please take action to approve or reject this request. \n \n To review, approve or reject the request, log into SaS, click Vacation Booking and click in Pending Approval link. \n \nNOTE: This is an Automated E-mail generated from the SaS mail process. Please do not reply to this E-mail. Vacation days Request Pending Approval");
email2.setText("<h3>Vacation Request<h3>\nYour vacation days request has been routed to your manager for approval. \n \nNote: If these dates should change, it is your responsibility to notify the appropriate people or withdraw your request in case you won't take those days.\n \nTo review, withdraw or modify your request, log into SaS, click Vacation Booking and check the current status or your Request. \n \nNOTE: This is an Automated E-mail generated from the SaS mail process. Please do not reply to this E-mail. Vacation days Request Routed for Approval");
mailSender.send(email2);
mailSender.send(emailPm);
System.out.println(booking.getFromDate());
bookingService.saveVacationBooking(booking);
ModelAndView modelAndView = new ModelAndView("myBookings");
String message = "the vacation booking was added!";
modelAndView.addObject("message", message);
return modelAndView;
}
and this is my view:
<!doctype html>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html class="no-js" lang="en">
<head>
<title>Vacation booking</title>
<link href="/vacation/resources/bootstrap-3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<!--Booking Form-->
<body>
<jsp:include page="../../templates/PageHeader.jsp" />
<form:form method="POST" style="width:800px;" commandName="booking" action="${pageContext.request.contextPath}/requestBooking/process" class="form-horizontal">
<div class="container">
<div class="row">
<div clas="col-md-12"><h4>Vacation Booking Form</h4></div>
<hr>
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">From:</label>
<div class="col-sm-6">
<form:input type="date" path="fromDate" class="form-control"></form:input>
<form:hidden path="user.userId" class="form-control"/>
<form:hidden path="bookingId" class="form-control"/>
<!--<input type="date" class="form-control"/> -->
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">To:</label>
<div class="col-sm-6">
<form:input type="date" path="toDate" class="form-control"></form:input>
<!-- <input type="date" class="form-control"/> -->
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Comments:</label>
<div class="col-sm-6">
<form:textarea path="comments" rows="4" class="form-control" placeholder="Fill this field if you have any comments related to your request"/>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-sm-6">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</div>
</form:form>
<jsp:include page="../../templates/PageFooter.jsp" />
<script src="/vacation/resources/js/jquery-2.0.3.min.js" type="text/javascript"></script>
<script src="/vacation/resources/bootstrap-3.0.3/js/bootstrap.min.js" type="text/javascript"></script>
</body>
</html>
When I try to do booking.getUser().getMail() I get null. It is like my "booking" object is null in my post method. Any idea of how I can get my booking with the user object inside in my post controller, so I can call the getUser() method?

Resources