I have only 2 page in my project "/register" and "/login". login.jsp page is coming from default spring security login. register.jsp is created by me.
My spring security configuration:
package com.cihangirmercan.security;
import org.springframework.beans.factory.annotation.Autowired;
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;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("cihangir").password("mercan")
.roles("USER"); // the only user at the beginning
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/register").permitAll() // anonym can login or register
.antMatchers("/").access("hasRole('USER')") // home page is not allowed if not user is logged in
.and().formLogin();
http.csrf().disable();
}
}
So, in the beginning, only one user id:"cihangir" and pass:"mercan" can pass the filter and login. What I want is after register with username and password, I want this new registration to has ROLE_USER and can login after that.
RegisterController:
package com.cihangirmercan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
#Controller
#SessionAttributes("registerWarning")
public class RegisterController {
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegisterPage(ModelMap model) {
return "register";
}
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String handleRegisterRequest(ModelMap model,
#RequestParam String username,
#RequestParam String password) {
// i want to give this username and password ROLE_USER
// hence user can login with spring security
// done
return "redirect:/login";
}
}
register.jsp:
<html>
<head>
<title>Register</title>
</head>
<body>
<h1>Register</h1>
<form action="/register" method="post" >
<label>Username:</label>
<input type="text" name="username" required><br><br>
<label>Password:</label>
<input type="password" name="password"><br><br>
<input type="submit" value="Register">
</form>
</body>
</html>
WelcomeController: (welcome page)
package com.cihangirmercan.controller;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class WelcomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String showWelcomePage(ModelMap model) {
model.put("username", getLoggedInUserName());
return "welcome";
}
private String getLoggedInUserName() {
Object principal = SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
if (principal instanceof UserDetails)
return ((UserDetails) principal).getUsername();
return principal.toString();
}
}
welcome.jsp:
<html>
<head>
<title>Home</title>
</head>
<body>
<h2>Home Page</h2>
<br>
<h4>${username} is at home.</h4>
</body>
</html>
Besides, web.xml and dispatcher-servlet and pom.xml they are all I have.
you have not configured your login correctly
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/register").permitAll() // anonym can login or register
.antMatchers("/").access("hasRole('USER')") // home page is not allowed if not user is logged in
.and().formLogin().loginPage("/login")
.and()
.logout().logoutSuccessUrl("/register");
http.csrf().disable();
}
and you have configured the view resolver in your dispatch-xxx.xml, something like this
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
I solved my problem with using jdbc authentication.
It dynamically updates users and roles.
source: https://dzone.com/articles/spring-security-4-authenticate-and-authorize-users
Related
I'm new in spring.
I was trying to add a new goal to my database. Before I add spring security it's worked, but now if I click to add a new goal, I have a problem :
There was an unexpected error (type=Forbidden, status=403).
Forbidden
My goat-add.html :
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Goals</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<header th:insert="blocks/header :: header"></header>
<div class="container mt-5 mb-5">
<h1>Your goals</h1>
<form action="/goal/add" method="post">
<input type="text" name="name" placeholder="Write your goal name" class="form-control"><br>
<textarea type="text" name="description" placeholder="Write your goal description" class="form-control"></textarea><br>
<button type="submit" class="btn btn-success">Add goal</button>
</form>
</div>
<div th:insert="blocks/footer :: footer"></div>
</body>
</html>
WebSecurityConfig class :
package com.evgzabozhan.GoatGoal.config;
import com.evgzabozhan.GoatGoal.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.crypto.password.NoOpPasswordEncoder;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login","/registration").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
My controller :
package com.evgzabozhan.GoatGoal.controller;
import com.evgzabozhan.GoatGoal.model.Goal;
import com.evgzabozhan.GoatGoal.model.User;
import com.evgzabozhan.GoatGoal.repository.GoalRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.RequestParam;
import java.util.*;
#Controller
public class GoalController {
#Autowired
private GoalRepository goalRepository;
#GetMapping("/goal")
public String goal(Model model){
Iterable<Goal> goals = goalRepository.findAll();
model.addAttribute("goals",goals);
return "goal/goal-main";
}
#GetMapping("/goal/add")
public String getGoalAdd(Model model){
return "goal/goal-add";
}
#PostMapping("/goal/add")
public String postGoalAdd(#AuthenticationPrincipal User user,
#RequestParam String name,
#RequestParam String description, Model model){
Goal goal = new Goal(name,description,user);
goalRepository.save(goal);
model.addAttribute("message",user.getUsername());
return "redirect:/goal";
}
#GetMapping("/goal/{id}")
public String goalInfo(#PathVariable(value = "id") long id, Model model) {
if (!goalRepository.existsById(id)) {
return "redirect:/goal";
}
Optional<Goal> goal = goalRepository.findById(id);
ArrayList<Goal> result = new ArrayList<>();
goal.ifPresent(result::add);
model.addAttribute("goal", result);
return "goal/goal-info";
}
#GetMapping("/goal/{id}/edit")
public String goalEdit(#PathVariable(value = "id") long id, Model model){
if (!goalRepository.existsById(id)) {
return "redirect:/goal";
}
Optional<Goal> goal = goalRepository.findById(id);
ArrayList<Goal> result = new ArrayList<>();
goal.ifPresent(result::add);
model.addAttribute("goal", result);
return "goal/goal-edit";
}
#PostMapping("/goal/{id}/edit")
public String postGoalUpdate(#PathVariable(value = "id") long id,
#RequestParam String name,
#RequestParam String description,
Model model){
Goal goal = goalRepository.findById(id).orElseThrow();
goal.setName(name);
goal.setDescription(description);
goalRepository.save(goal);
return "redirect:/goal";
}
#PostMapping("/goal/{id}/remove")
public String postGoalRemove(#PathVariable(value = "id") long id, Model model){
Goal goal = goalRepository.findById(id).orElseThrow();
goalRepository.delete(goal);
return "redirect:/goal";
}
}
I read this problem can be if don't use csrf, but I don't understand how I can fix it.
All code there: https://github.com/evgzabozhan/GoatGoal
Thanks for your help!
I think this is because none of the goal calls is a permitted operation
.antMatchers("/login","/registration").permitAll()
should be
.antMatchers("/login","/registration","/goal").permitAll()
I add .csrf.disable() in configure method and it's work.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login","/registration").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
it's working because crsf is enabled on default in Spring
I want to implement one thing in my project, but it does not work. I have a jsp page with a list of students(allStudents.jsp), I want when the project starts so that the login page comes out and after such as the admin enters his login and password only when he could immediately go to the page where the list of students. But my project does not ask me to enter my login and password and immediately opens the page where the list of students is.
AuthorizationController.jsp
package adil.java.schoolmaven.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class AuthorizationController{
// If user will be successfully authenticated he/she will be taken to the login secure page.
#RequestMapping(value="/admin", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView m = new ModelAndView();
m.addObject("title", "You have successfully logged in.");
m.addObject("message", "Home");
m.setViewName("admin");
return new ModelAndView("redirect: allStudents");
}
// Spring security will see this message.
#RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView login(#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout) {
ModelAndView m = new ModelAndView();
if (error != null) {
m.addObject("error", "Invalid username and password");
}
if (logout != null) {
m.addObject("msg", "you successfully logged out");
}
m.setViewName("login");
return new ModelAndView("redirect: allStudents");
}
}
Student Controller
package adil.java.schoolmaven.controller;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
import adil.java.schoolmaven.entity.Student;
import adil.java.schoolmaven.service.StudentService;
import java.nio.file.FileSystemException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class StudentController {
#Autowired
private ServletContext servletContext;
// Constructor based Dependency Injection
private StudentService studentService;
public StudentController() {
}
#Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
#RequestMapping(value = "/allStudents", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView displayAllUser() {
System.out.println("User Page Requested : All Students");
ModelAndView mv = new ModelAndView();
List<Student> studentList = studentService.getAllStudents();
mv.addObject("studentList", studentList);
mv.setViewName("allStudents");
return mv;
}
#RequestMapping(value = "/addStudent", method = RequestMethod.GET)
public ModelAndView displayNewUserForm() {
ModelAndView mv = new ModelAndView("addStudent");
mv.addObject("headerMessage", "Add Student Details");
mv.addObject("student", new Student());
return mv;
}
#PostMapping(value = "/addStudent")
public String saveNewStudent(#RequestParam("name") #NonNull String name,
#RequestParam("surname") #NonNull String surname,
#RequestParam("avatar") MultipartFile file)
throws IOException {
Student student = new Student();
student.setSurname(surname);
student.setName(name);
if (file != null && !file.isEmpty()) {
student.setAvatar(studentService.saveAvatarImage(file).getName());
}
studentService.saveStudent(student);
return "redirect:/allStudents";
}
#GetMapping(value = "/editStudent/{id}")
public ModelAndView displayEditUserForm(#PathVariable Long id) {
ModelAndView mv = new ModelAndView("editStudent");
Student student = studentService.getStudentById(id);
mv.addObject("headerMessage", "Редактирование студента");
mv.addObject("student", student);
return mv;
}
#PostMapping(value = "/editStudent")
public String saveEditedUser(
#RequestParam("id") Long id,
#RequestParam("name") String name,
#RequestParam("surname") String surname,
#RequestParam("avatar") MultipartFile file) {
try {
studentService.updateStudent(name, surname, file, studentService.getStudentById(id));
} catch (FileSystemException ex) {
ex.printStackTrace();
} catch (IOException e) {
return "redirect:/error";
}
return "redirect:/allStudents";
}
#GetMapping(value = "/deleteStudent/{id}")
public ModelAndView deleteUserById(#PathVariable Long id) {
studentService.deleteStudentById(id);
ModelAndView mv = new ModelAndView("redirect:/allStudents");
return mv;
}
}
mvc-dispacther-serlvet
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="adil.java.schoolmaven" />
<!-- Resolves Views Selected For Rendering by #Controllers to *.jsp Resources in the /WEB-INF/ Folder -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
login.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Custom login</title>
<style type="text/css">
.error {
color: #ff0000;
font-weight: bold;
}
.msg {
color: #008000;
font-weight: bold;
}
</style>
</head>
<body>
<h1 id="banner">Custom login form</h1>
<!-- invalid credentials error msg -->
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>
<!-- logged out msg -->
<c:if test="${not empty msg}">
<div class="msg">${msg}</div>
</c:if>
<!-- custom login form -->
<form name="loginform" action="<c:url value='/login'/>" method="POST">
<table>
<tr>
<td>Логин:</td> <!-- Enter username -->
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Пароль:</td> <!-- Enter password -->
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
admin.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# page language="java" session="true" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Secure page</title>
</head>
<body>
<h1>Title : ${title}</h1>
<h1>Message : ${message}</h1>
<!-- displaying the logged in user details. -->
<c:if test="${pageContext.request.userPrincipal.name != null}">
<span>Welcome: ${pageContext.request.userPrincipal.name}</span> | <span><a id="logout" href="${pageContext.servletContext.contextPath}/logout">Logout</a></span>
</c:if>
</body>
</html>
enter image description here
You need to configure Spring Security Config class that implements WebSecurityConfigurerAdapter. And configure your login page as a parameter. Please see my code for reference. And also go through this tutorial and try to implement it. It will give you good knowledge on how to setup things.
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
private final MyUserDetailsService userDetailsService;
private final CustomBasicAuthenticationEntryPoint customBasicAuthenticationEntryPoint;
#Autowired
public SecurityConfig(MyUserDetailsService userDetailsService, CustomBasicAuthenticationEntryPoint customBasicAuthenticationEntryPoint)
{
this.userDetailsService = userDetailsService;
this.customBasicAuthenticationEntryPoint = customBasicAuthenticationEntryPoint;
}
#Override
public void configure(AuthenticationManagerBuilder auth)
{
auth.authenticationProvider(getDaoAuthenticationProvider());
}
#Bean
public CustomDaoAuthenticationProvider getDaoAuthenticationProvider()
{
CustomDaoAuthenticationProvider daoAuthenticationProvider=new CustomDaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(getBCryptPasswordEncoder());
return daoAuthenticationProvider;
}
/* BCrypt strength should 12 or more*/
#Bean
public PasswordEncoder getBCryptPasswordEncoder()
{
return new BCryptPasswordEncoder(12);
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/anonymous*").anonymous()
.antMatchers("/register").permitAll()
.antMatchers("/users/**").hasAuthority(AuthorityConstants.ADMIN)
.antMatchers("/admin**").hasAuthority(AuthorityConstants.ADMIN)
.antMatchers("/profile/**").hasAuthority(AuthorityConstants.USER)
.antMatchers("/api/**").hasAnyAuthority(AuthorityConstants.API_USER,AuthorityConstants.ADMIN)
.antMatchers("/dba/**").hasAuthority(AuthorityConstants.DBA)
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.exceptionHandling()
.authenticationEntryPoint(customBasicAuthenticationEntryPoint)
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.successHandler(new CustomAuthenticationSuccessHandler(sessionHistoryRepository))
.failureHandler(new CustomAuthenticationFailureHandler(failedLoginRepository))
.permitAll()
.and()
.logout()
.deleteCookies("X-Auth-Token")
.clearAuthentication(true)
.invalidateHttpSession(true)
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler(unauthorizedRequestRepository))
.and()
.rememberMe().rememberMeServices(springSessionRememberMeServices());
// Uses CorsConfigurationSource bean defined below
http.cors();
http.sessionManagement()
//.invalidSessionUrl("/login.html")
//.invalidSessionStrategy((request, response) -> request.logout())
.sessionFixation().migrateSession()
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
.sessionRegistry(sessionRegistry());
http.csrf()
.disable();
http.authorizeRequests()
.antMatchers("/").permitAll()
.and()
.authorizeRequests().antMatchers("/console/**","/h2-console/**").permitAll();
http.headers()
.frameOptions().disable();
}
#Bean
public SpringSessionRememberMeServices springSessionRememberMeServices()
{
SpringSessionRememberMeServices rememberMeServices = new SpringSessionRememberMeServices();
rememberMeServices.setRememberMeParameterName("remember-me");
rememberMeServices.setValiditySeconds(ApplicationConstants.REMEMBERMETIMEOUT);
return rememberMeServices;
}
//Cors filter to accept incoming requests
#Bean
CorsConfigurationSource corsConfigurationSource()
{
CorsConfiguration configuration = new CorsConfiguration();
configuration.applyPermitDefaultValues();
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
public void configure(WebSecurity web) throws Exception
{
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/h2-console/**","/console/**");
}
#Bean("authenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
#Bean
public SessionRegistry sessionRegistry()
{
return new SessionRegistryImpl();
}
}
I have configured all the settings for my spring project, but when I try to login in to the application, it says for each request that
"The server understood the request but refuses to authorize it."
Initially I tried to implement JDBC Authentication, (you can see that I am using the Datasource in my code). But then I tried with in memory authentication too, in both cases, I am unable to access the resources.
Below is my spring config file,
package com.nobalg.config;
import java.beans.PropertyVetoException;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.mchange.v2.c3p0.ComboPooledDataSource;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.nobalg")
#PropertySource("classpath:persistence-mysql.properties")
public class AppConfig {
#Autowired
private Environment env;
private Logger logger = Logger.getLogger(getClass().getName());
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public DataSource secureDataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
//Datasource
dataSource.setDriverClass(env.getProperty("jdbc.driver"));
dataSource.setJdbcUrl(env.getProperty("jdbc.url"));
dataSource.setUser(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.password"));
//Connection polling
dataSource.setInitialPoolSize(Integer.parseInt(env.getProperty("connection.pool.initialPoolSize")));
dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("connection.pool.maxPoolSize")));
dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("connection.pool.minPoolSize")));
dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("connection.pool.maxIdleTime")));
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
return dataSource;
}
}
Dispatcher Servlet Initializer file
package com.nobalg.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MvcSpringInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class[]{AppConfig.class};
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[]{"/"};
}
}
Spring security configuration file :
package com.nobalg.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
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;
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//auth.jdbcAuthentication().dataSource(dataSource);
auth.inMemoryAuthentication().withUser("Nobal").password("test#123").authorities("MANAGER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/loginPage")
.loginProcessingUrl("/loginProcessing")
.usernameParameter("username")
.passwordParameter("password")
.permitAll();
}
}
Spring security initializer file
package com.nobalg.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
The one and only controller
package com.nobalg.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
#Controller
public class MainContoller {
#GetMapping("/loginPage")
public String showLoginForm(){
return "login";
}
}
and the login page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form:form method="POST" action="${pageContext.request.contextPath}/loginProcessing">
<p>Enter Username : <input type="text" placeholder="Enter Username" name="username"></p>
<p>Enter Password : <input type="password" placeholder="Enter Password" name="password"></p>
<p><input type="submit" value="LOG IN"></p>
</form:form>
</body>
</html>
Add this as your form field:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
Or if you want other approach with Spring Security JSP tag library:
Optionally you can disable csrf, which is enabled by default:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
Edit1
Add this bean with passwordEncoder.
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
And set password encoder to auth:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.passwordEncoder(this.passwordEncoder());
}
Edit2
Change .loginProcessingUrl("/loginProcessing") which needs UserDetailsService to .defaultSuccessUrl("/")
I'm making with using spring and hibernate. In my database i'm having several users with 3 different roles. I'm using BCryptPasswordEncoder, in database i'm having users with plain password, encoded password and {bcrypt}encoded password, i'm having problem becouse when i type users with plain passwords i can login, when i type password encoded or {bcrypt}encoded i can't login.
SecurityConfig.java
package com.spring.config;
import com.spring.service.UserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth ) throws Exception {
auth.authenticationProvider(authProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/managers/**").hasRole("MANAGER")
.antMatchers("/employees/**").hasRole("REGULAR_EMPLOYEE")
.antMatchers("/").permitAll()
.and().formLogin().loginPage("/").defaultSuccessUrl("/login").loginProcessingUrl("/loginAction").permitAll()
.and().logout().permitAll();
}
#Bean
public UserDetailsService userDetailsService(){
return new UserDetails();
}
#Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(bCryptPasswordEncoder());
return authProvider;
}
}
UserDetails.java
package com.spring.service;
import com.spring.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class UserDetails implements UserDetailsService {
#Autowired
private UserService mUserService;
#Override
public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = mUserService.getUserByLogin(s);
org.springframework.security.core.userdetails.User.UserBuilder userBuilder;
userBuilder = org.springframework.security.core.userdetails.User.withUsername(user.getAccountLogin());
userBuilder.password(new BCryptPasswordEncoder().encode(user.getAccountPassword()));
userBuilder.roles(user.getRoleByRoleId().getRole());
return userBuilder.build();
}
}
plain-login.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Log in</title>
<meta charset="UTF-8">
<style>
.failed {
color: red;
}
.success {
color: green;
}
</style>
</head>
<body>
<form:form action="${pageContext.request.contextPath}/loginAction"
method="POST">
<c:if test="${param.error != null}">
<i class="failed">Wrong data!</i>
</c:if>
<c:if test="${param.logout != null}">
<i class="success">Logged out successfully!</i>
</c:if>
<p>
Login: <input type="text" name="username" />
</p>
<p>
Password: <input type="password" name="password" />
</p>
<input type="submit" value="Log in" />
</form:form>
</body>
</html>
I am getting this error while adding Assets folder.
It is giving error for every file which is included from "assets" folder.
WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/assets/plugins/datepicker/datepicker3.css] in DispatcherServlet with name 'dispatcher'
Here is the Dispacther Config file
package com.springmaven.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan({"com.springmaven.controller"})
public class DispatcherConfig {
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver()
{
InternalResourceViewResolver internalResourceViewResolver=new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("/WEB-INF/JSP/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
}
This is App Config
package com.springmaven.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppIntializer implements WebApplicationInitializer{
#Autowired
public void onStartup(ServletContext servletCon) throws ServletException {
// TODO Auto-generated method stub
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationConfig.class);
servletCon.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext servletConfig = new AnnotationConfigWebApplicationContext();
servletConfig.register(DispatcherConfig.class);
ServletRegistration.Dynamic registration = servletCon.addServlet("dispatcher", new DispatcherServlet(servletConfig));
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
This is security Config
package com.springmaven.config;
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.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.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private AuthenticationProvider customAuthenticationProvider;
#Autowired
CustomSuccessHandler customSuccessHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/assets/**");
}
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(customAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/assets/**").permitAll()
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and().csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
#Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
private CsrfTokenRepository csrfTokenRepository()
{
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setSessionAttributeName("_csrf");
return repository;
}
}
Folder Structure
source->main->webapp->WEB-INF->JSP->assets(This folder is not recognised)
source->main->webapp->WEB-INF->JSP->homePage.jsp
From the Style or Icon is not coming in homePage.
homePage.jsp
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>New Member</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<!--Favicon Image -->
<link rel="shortcut icon" href="assets/dist/img/favicon.ico"/>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" href="assets/plugins/datepicker/datepicker3.css">
</head>
<body>
Welcome,
<form id="logout" action="${Signout}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
Logout
</c:if>
</body>
</html>
You need to add support for static web resources.
To configure it to be managed by Spring see this question, for example.