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>
Related
My login is not doing anything. I made a similar project and there it worked. The Register is working, but the Login button is not doing anything. Any ideas why is not working?
I'll put my DemoApplication, SecurityConfig and login.html down.
login.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link href = '../css/login.css' rel = 'stylesheet'>
<title> Login </title>
</head>
<body>
<div class = "panel">
<form class="login-form" th:action="#{/DS_login}" method="post">
<input id = "loginButton" type="image" src="../img/b1.gif" name = "login" value="Login">
<p> Login </p>
<br>
<br>
<label> username </label>
<br>
<input type = "text" name = "username">
<br>
<label> password </label>
<br>
<input type = "password" name = "password">
<br>
<p id = "wrongLogin">Wrong credentials</p>
</form>
<p class="message">Not registered? <a th:href = "#{/DS_Register}" href = "register.html">Register</a></p>
</div>
</body>
</html>
-DemoApplication
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#SpringBootApplication
public class DemoApplication implements WebMvcConfigurer{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/DS_login").setViewName("login");
}
}
-SecurityConfig
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/DS_Register").permitAll()
.anyRequest().authenticated().and().formLogin().loginPage("/DS_login").permitAll();
http.formLogin()
.loginPage("/DS_login")
.defaultSuccessUrl("/DS_Home",true);
}
}
---- please help ----
You should avoid using the type="image" as it is problematic because the ability to pass a value is disabled.
Use a button instead.
<button type="submit" name="someName" value="someValue"><img src="someImage.png" alt="SomeAlternateText"></button>
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();
}
}
..this happens the first time when project is recently started.
After login for the first time and make logout- styles continue to work as needed.
Why is this happening?
P.S. Sorry for my bad english
here's what the browser console says:
auth:1 Refused to apply style from 'http://localhost:8080/auth'
because its MIME type ('text/html') is not a supported stylesheet MIME
type, and strict MIME checking is enabled.
SecurityConfiguration:
package config;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import javax.sql.DataSource;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).
usersByUsernameQuery("select login,password,true from user where login=?").
authoritiesByUsernameQuery("select login, role from user where login=?");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http .authorizeRequests()
.antMatchers("/auth", "/reg").permitAll()
.antMatchers("/admin/**").hasAuthority("admin")
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/auth").usernameParameter("login")
.permitAll()
.and()
.logout().logoutSuccessUrl("/auth");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
}
Authorization.jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Authorization</title>
<c:set var="root" value="${pageContext.request.contextPath}"/>
<link type="text/css" rel="stylesheet" href="styles.css"/>
</head>
<body>
<div class="container">
<div class="mainblock">
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<form method="post" action="/auth">
User Name : <input type="text" name="login">
Password : <input type="password" name="password">
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<input name = "submit" value = "Authorize" type = "submit" />
</form>
<p>Did not create an account?
Registration
</p>
</div>
</div>
</body>
</html>
The styles file is in the "web" package along with Authorizatiom.jsp
All this was due to my carelessness and the specified wrong directory, which is specified in configure (WebSecurity web). I needed to add "vendor / **"
Also i defined the content path: <link rel = "stylesheet" href = "$ {pageContext.request.contextPath} /vendor/css/styles.css">
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 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