I'm new in Java, and currently try to create my own project, but have a problem with displaying information about user in his main page. Now I need to save a value from my JSP page (/login) which use method POST into parameter of my Java class("Controller").
login.jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Log in with your account</title>
<link href="${contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
<link href="${contextPath}/resources/css/common.css" rel="stylesheet">
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
<div class="container">
<form method="POST" action="${contextPath}/login" class="form-signin">
<h2 class="form-heading">Log in</h2>
<div class="form-group ${error != null ? 'has-error' : ''}">
<span>${message}</span>
<input name="email" type="text" class="form-control" placeholder="Email"
autofocus="true"/>
<input name="password" type="password" class="form-control" placeholder="Password"/>
<span>${error}</span>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<button class="btn btn-lg btn-primary btn-block" type="submit">Log In</button>
<h4 class="text-center">Create an account</h4>
</div>
</form>
</div>
<!-- /container -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="${contextPath}/resources/js/bootstrap.min.js"></script>
</body>
</html>
and UserController
#RequestMapping(value = "/registration", method = RequestMethod.GET)
public String registration(Model model) {
model.addAttribute("userForm", new User());
return "registration";
}
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute("userForm") User userForm, BindingResult bindingResult, Model model) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.save(userForm);
securityService.autoLogin(userForm.getEmail(), userForm.getConfirmPassword());
return "redirect:/fillingform";
}
#RequestMapping(value = "/login")
public String getEmail(#RequestParam("email") String email) {
return email;
}
appconfig-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true">
<intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
<intercept-url pattern="/welcome" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')"/>
<form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error"
username-parameter="email" password-parameter="password"/>
<logout logout-success-url="/login?logout"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsServiceImpl">
<password-encoder ref="encoder"></password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="userDetailsServiceImpl"
class="com.gmail.*">
</beans:bean>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11"/>
</beans:bean>
</beans:beans>
UserDetailsServImpl
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserDao userDao;
#Override
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userDao.findByEmail(email);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), grantedAuthorities);
}
}
Read a lot of information, if for real about it,heard recommendation about doPost() method, request.getParameter() and so on, but nothing help (
Please help, what logic code I need to put in method "public String getEmail" for getting user Emailfrom POST form.
Thank's.
Related
I am using Spring Boot/Thymeleaf to create a form that accepts an email address, redirects to a results page that displays the accepted email and sends it to a third party API (authenticated with Oauth2). I am having trouble with the form portion, I am attempting to use Thymeleaf to accept the input to display it on the result.html page. I am receiving an error when trying to display it on the results page, full error is:
[THYMELEAF][http-nio-8080-exec-4] Exception processing template "result.html": Exception evaluating SpringEL expression: "signup.email" (template: "result.html" - line 10, col 4)
I was attempting to follow the examples provided here:
https://spring.io/guides/gs/handling-form-submission/
I have attempted to modify the controller from #PostMapping and #GetMapping to #RequestMapping and add commenting described in a workaround such as:
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
Here is the signup.html code containing the form:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<title>My Jmml</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body style="background-color: #2B2B2B">
<br /><br />
<h2 style="text-align:center">Contact Information</h2>
<!-- Input Form -->
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
<form action="#" th:action="#{/signup}" th:object="${signup}" method="post">
<div align="center">
<label>Email Address</label><br /><br />
<!--/*#thymesVar id="email" type="String"*/-->
<input type="text" th:field="*{email}" placeholder="Email" required />
<br />
<br />
<input class="submitbutton" type='submit' value='Submit'/>
<br />
</div>
</form>
</body>
</html>
Results page that should display the email (result.html):
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thank you for your submission!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Thank you for your submission!</h1>
<p th:text="'Email: ' + ${signup.email}" />
Submit another message
</body>
</html>
Controller:
#Controller
public class controller1 {
#RequestMapping (value = "/home")
public String home(Model model) {
return "index.html";
}
#RequestMapping(value = "/signup", method= RequestMethod.GET)
public String signupForm(Model model) {
model.addAttribute("signup", new emailInput());
return "signup.html";
}
#RequestMapping(value = "/signup", method= RequestMethod.POST)
public String signupSubmit(#ModelAttribute("email") emailInput email) {
return "result.html";
}
}
Expected output should be the email variable displayed on the results page after it being gathered in the signup form.
If you have a recommendation on how to better do what I am attempting, I am open to suggestions! I am very new to Spring/Thymeleaf but have had experience with Java/Jsp. Thank you for any help, please let me know if you need anything else to help!
Hopefully this will be a starting point for you.
Make sure you place the html files under /resources/templates.
I changed a bit your signup html and result.html as follows, they are still not perfect(avoid using inline styles and use an external stylesheet!):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>My Jmml</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body style="background-color: #2B2B2B">
<br /><br />
<h2 style="text-align:center">Contact Information</h2>
<!-- Input Form -->
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
<form th:action="#{/signup}" th:object="${signup}" method="post">
<div align="center">
<label>Email Address</label><br /><br />
<!--/*#thymesVar id="email" type="String"*/-->
<input type="text" th:field="*{email}" placeholder="Email" />
<br />
<br />
<input class="submitbutton" type="submit" value="Submit"/>
<br />
</div>
</form>
</body>
and the result.html looks like this
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>Thank you for your submission!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Thank you for your submission!</h1>
<p th:text="'Email: ' + ${email}" />
Submit another message
</body>
</html>
I also created a form object, add additional fields here if you want
public class SignUpForm {
//you can put some annotations here if you want for validating the email
//for e.g #NotEmpty or a #Pattern(regexp to validate the email)
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
and in the end your Controller. I pass the email from the signup post request to the result.html via a flash attribute:
#Controller
public class Controller1 {
#RequestMapping(value = "/signup", method= RequestMethod.GET)
public String signupForm(#ModelAttribute("signup") SignUpForm form) {
return "/signup";
}
#RequestMapping(value = "/signup", method= RequestMethod.POST)
public String signupSubmit(#ModelAttribute("signup") SignUpForm form, RedirectAttributes redirectAttributes) {
//validate form first -> check bindingResult documentation
//do what you need with your form object
redirectAttributes.addFlashAttribute("email", form.getEmail());
return "redirect:/result";
}
#RequestMapping(value = "/result", method= RequestMethod.GET)
public String result() {
return "/result";
}
}
I am using Spring security configurations for login authentication in order to check for the valid credentials. How can I redirect the application to my custom login page. I tried to implement form-login as shown below, but it did not work for me, Please help me to resolve this.
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<http auto-config='true'>
<intercept-url pattern="/secured/*" access="ROLE_USER" />
<form-login
login-page='/login'
default-target-url="/home"
authentication-failure-url="/error" />
<logout logout-success-url="/logout" />
</http>
<authentication-manager>
<authentication-provider ref="customAuthenticationProvider"/>
</authentication-manager>
</beans:beans>
In the above code, login, logout, error and home are my custom pages.
Following is my controller code.
#Controller
public class LoginController {
#RequestMapping(value="/", method=RequestMethod.GET)
public String dashboard(){
System.out.println("Dashboard method of Login Controller");
return "dashboard";
}
#RequestMapping(value="/login", method=RequestMethod.GET)
public String getLoginForm(){
System.out.println("Login method of Login Controller");
return "login";
}
#RequestMapping(value="/logout", method=RequestMethod.GET)
public String getLogoutForm(){
System.out.println("Logout method of Login Controller");
return "logout";
}
#RequestMapping(value="/error", method=RequestMethod.GET)
public String loginAgain(){
// ModelAndView model = new ModelAndView("Login");
System.out.println("error method of Login Controller");
return "error";
}
#RequestMapping(value="/secured/test", method=RequestMethod.GET)
public String getData(ModelMap model){
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
System.out.println("Returned .... "+principal);
System.out.println("Returned object name is :: "+principal.toString());
model.addAttribute("username", "John");
model.addAttribute("message", "Welcome to the secured page");
return "home";
}
Following is the login page.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<!DOCTYPE Html>
<html lang="en">
<title>Aventyn®| Login</title>
<head>
<link type="text/css" rel="stylesheet" href='<spring:url value="/resources/css/bootstrap.min.css" />' >
<link type="text/css" rel="stylesheet" href='<spring:url value="/resources/css/loginCSS.css" />'>
</head>
<body>
<div class="container-fluid">
<form action="http://localhost:8080/LoginMavenSpringMVC/secured/test" method="get">
<div class="row margin_Div">
<div class="col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title text-center"><strong>Login Page</strong></h2>
</div>
<div class="panel-body">
<div class="row">
<div class="col-sm-3 col-md-2">
<b>Login Id:</b>
</div>
<div class="col-sm-4 col-md-3">
<div class="input-group">
<span class="input-group-addon">*</span>
<input type="text" class="form-control input-sm" placeholder="LoginId" name="UserName">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3 col-md-2">
<b>Password:</b>
</div>
<div class="col-sm-4 col-md-3">
<div class="input-group">
<span class="input-group-addon">*</span>
<input type="text" class="form-control input-sm" placeholder="Password" name="Password">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3 col-md-2"></div>
<div class="col-sm-4 col-md-3">
<button class="form-control btn-sm btn-primary" type="submit">Login</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<p>${SucessMsg}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</body>
<script type="text/javascript" src='<spring:url value=" /resources/js/jquery.min.js"/>'></script>
<script type="text/javascript" src=' <spring:url value="/resources/js/bootstrap.min.js"/>'></script>
</html>
Excaption i am getting
HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
I am trying to implement spring security via custom login page
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<!-- <http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<http-basic/>
</http> -->
<!-- <http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<form-login/>
<logout logout-success-url="/home"/>
</http> -->
<http>
<intercept-url pattern ="/welcome*" access="hasRole('ROLE_USER')"/>
<form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/loginfailed"/>
<logout logout-success-url="/logout"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="rahul" password="123" authorities="ROLE_USER"/>
<user name="rohit" password="567" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
login.jsp
<%# page language="java" 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>Login Page</title>
<!-- <style>
.errorblock
{
color : #f0000;
background-color : #ffEEEE;
border : 3px solid #ff0000;
padding : 8px;
margin : 16px;
}
</style> -->
</head>
<body onload='document.f.j_username.focus();' bgcolor="blue">
<h3>Login with Username andPassword (Custom page)</h3>
<%-- <c:if test="$SPRING_SECURITY_LAST_EXCEPTION !=null"}">
<div class="errorblock">
Your login atempt are not sucessfull,try again
<br/>Caused : ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message }
</div>
</c:if> --%>
<%-- <form name='f' action="<c:url value='j_spring_security_logout'/>" method="POST">
--%>
<form name='f' action='/SpringSecurityApplication/login' method="POST">
<table>
<tr>
<td>User :</td><td><input type='text' name='username'></td>
</tr>
<tr>
<td>Password :</td><td><input type='password' name='password'></td>
</tr>
<tr><td colspan ='2'><input name="submit" type="submit" value="submit" ></td></tr>
<tr><td colspan ='2'><input name="reset" type="reset" ></td></tr>
</table>
</form>
</body>
</html>
LoginController.java
package com.springtraining.security.controller;
import java.security.Principal;
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 LoginController {
public LoginController() {
System.out.println("LoginController constructor is called ");
}
#RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String printWelcome(ModelMap model, Principal principal) {
System.out.println("**********Login Controller is Called********");
String name = principal.getName();
model.addAttribute("username", name);
model.addAttribute("message", "Spring Security Custom Form Example");
return "hello";
}
#RequestMapping(value = "/*", method = RequestMethod.GET)
public String home(ModelMap model) {
return "home";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model) {
return "login";
}
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model) {
return "login";
}
#RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
public String loginError(ModelMap model) {
model.addAttribute("error","true");
return "login";
}
}
hello.jsp
home.jsp
I think not required
You need to submit the crsf token while login (and logout and every other
POST, PUT, DELETE request).
There are serveral ways to add this to your jsp:
use spring's jsp <form:form> tag (instead the standart form tag) or
you need to add the crsf token explicit, either by spring security tag <sec:csrfInput /> or:
by "standart jsp":
"standart jsp" example:
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
#see: Spring Security Reference Chapter 18.4.3 Include the CSRF Token
BTW: I strongly recommend to read the complete Chapter 18. Cross Site Request Forgery (CSRF)
Hei guys! I have a servlet config as below.
vietjob-servlet
<mvc:annotation-driven />
<context:component-scan base-package="vjb.de.vietjob" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:view-controller path="/" view-name="index" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:lang" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
And in web xml i declare the uri for servlet
web.xml
<servlet>
<servlet-name>vietjob</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>vietjob</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
If i write all controller request mapping under /, everything is ok, servlet can load all libraries inside resources folder. But when i give controller a segment, i got error with
WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI
For details the link localhost:8001/vjb.de/ehdokas.do is working but localhost:8001/vjb.de/employee/ehdokas.do not work. I guess that when i give a segment, the servlet will scan employee/resources instead /resources, so the error occurred.
And another issue: when user login into system, the link was changed from http://localhost:8001/vjb.de/ehdokas.do to http://localhost:8001/vjb.de/employee/ehdokas.do. How can i config a same controller with all urls, i mean controller can run without relative to url address. Every link abc/def/ehdokas.do or abc/ehdokas.do also call to controller ehdokas.do?!
Controller class
#Controller
#RequestMapping(value = "/employee")
public class EhdokasController {
#Inject
private EhdokasDao ehdokasdao;
#Inject
private AlaDao aladao;
public AlaDao getAlaDao(){
return aladao;
}
public void setAlaDao(AlaDao aladao){
this.aladao=aladao;
}
public EhdokasDao getEhdokasDao() {
return ehdokasdao;
}
public void setEhdokasDao(EhdokasDao ehdokasdao) {
this.ehdokasdao = ehdokasdao;
}
#RequestMapping(value="/", method=RequestMethod.GET)
public String showEmployeePage(#RequestParam(value="tunnus") String tunnus, Model model){
System.out.println("ehdokasdao: "+ehdokasdao);
EhdokasImpl ehdokas = (EhdokasImpl) ehdokasdao.getEhdokasByTunnus(tunnus);
model.addAttribute("ehdokas", ehdokas);
return "ehdokas/ehdokas_home";
}
// Siirtää ehdokas lomake sivulle
#RequestMapping(value = "/lomake.do", method = RequestMethod.GET)
public String forwardToLomake(Model model) {
Ehdokas ehdokas = new EhdokasImpl();
List<Integer> listId = aladao.getListAlaId();
model.addAttribute("listId", listId);
model.addAttribute("ehdokas", ehdokas);
return "lomake/lomake_ehdokas";
}
// ota syötetyt tiedot lomakkeesta
#RequestMapping(value = "/lomake.do", method = RequestMethod.POST)
public String getTietoLomake(
#ModelAttribute(value = "ehdokas") #Valid EhdokasImpl ehdokas, BindingResult result, Model model) {
if (result.hasErrors()) {
return "lomake/lomake_ehdokas";
} else {
ehdokasdao.postEhdokas(ehdokas);
return "redirect:/ehdokas.do";
}
}
// näytä kaikki ehdokkaat tietokannasta
#RequestMapping(value = "/ehdokas.do", method = RequestMethod.GET)
public String showEhdokkaat(Model model) {
List<String> kaupunkiList = ehdokasdao.getKotiKaupunki();
List<Ehdokas> ehdokkaat = ehdokasdao.showEhdokas();
model.addAttribute("ehdokkaat", ehdokkaat);
model.addAttribute("kaupunkiList", kaupunkiList);
model.addAttribute("ehdokas", new EhdokasImpl());
return "ehdokas/ehdokas_list";
}
#RequestMapping(value = "/ehdokas.do", method = RequestMethod.POST)
public String showEhdokkaat(
#ModelAttribute(value = "ehdokas") EhdokasImpl ehdokas,#PathVariable(value="kaupunki") String kaupunki, #PathVariable(value="id") int id,#RequestParam(value="submit") String submit, Model model) {
System.out.println(submit);
if(submit.equals("Hae") || submit.equals("Search")){
List<String> kaupunkiList = ehdokasdao.getKotiKaupunki();
List<Ehdokas> ehdokkaat = ehdokasdao.getEhdokasByKaupunki(kaupunki);
model.addAttribute("ehdokkaat", ehdokkaat);
model.addAttribute("kaupunkiList", kaupunkiList);
return "ehdokas/ehdokas_list";
} else if (submit.equals("More") || submit.equals("Lisätieto")){
model.addAttribute("id",id);
return "redirect:yksiehdokas.do";
} else
return "redirect:ehdokas.do";
}
#RequestMapping(value="/yksiehdokas.do", method=RequestMethod.GET)
public String showYksiEhdokas(#RequestParam(value="id") int id, Model model ){
Ehdokas ehdokas = ehdokasdao.searchEhdokasById(id);
model.addAttribute("ehdokas", ehdokas);
return "ehdokas/ehdokas_yksi";
}
/*siirrä apply sivulle*/
#RequestMapping(value="/apply.do", method= RequestMethod.GET)
public String forwardToApply(Model model){
Kayttaja kayttaja = new KayttajaImpl();
Ehdokas ehdokas = new EhdokasImpl();
model.addAttribute("kayttaja", kayttaja);
model.addAttribute("ehdokas", ehdokas);
return "apply";
}
#RequestMapping(value="/apply.do", method= RequestMethod.POST)
public String getInfoEmployee(#ModelAttribute(value="ehdokas") EhdokasImpl ehdokas){
ehdokasdao.postEhdokas(ehdokas);
return "redirect:ehdokas.do";
}
#ModelAttribute("kieliList")
public List<String> getKieli() {
List<String> list = new ArrayList<String>();
list.add("English");
list.add("Finnish");
list.add("Germany");
return list;
}
#ModelAttribute("tutkinnot")
public List<String> getTutkinto() {
List<String> list = new ArrayList<String>();
list.add("Päiväkoti");
list.add("Peruskoulu");
list.add("Lukio");
list.add("AMK");
list.add("Yliopisto");
return list;
}
}
Jsp file
<%# page session="false"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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">
<%# include file="/WEB-INF/views/templates/navbar-bootstrap.jsp"%>
<%# include file="/WEB-INF/views/templates/logo-banner.jsp"%>
<%# include file="/WEB-INF/views/templates/menu-bootstrap.jsp"%>
<script src="<c:url value="resources/bootstrap-3.3.6/js/bootstrap.min.js" />"></script>
<link href="resources/bootstrap-3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="resources/js/jquery-1.12.2.min.js"></script>
<style>
/* Set black background color, white text and some padding */
.container-fluid {
width: 1000px;
margin: auto;
}
.form-control{
width: 30px;
}
</style>
<title><spring:message code="employee.page.list" /></title>
</head>
<body>
<div class="container-fluid text-center">
<div class="row content">
<div class="col-sm-2 sidenav">
<p>Link</p>
<p>Link</p>
<p>Link</p>
</div>
<div class="col-sm-8 text-left">
<form:form class="form-inline" action="ehdokas.do" modelAttribute="ehdokas" method="POST">
<form:select class="form-control" path="kaupunki">
<form:option value="">select city</form:option>
<form:options items="${kaupunkiList}"></form:options>
</form:select>
<spring:message code="button.search" var="search" />
<input type="submit" name="submit" value="${search }" />
</form:form>
<h3><spring:message code="kaikki.ehdokas"></spring:message></h3>
<hr>
<table class="table table-striped">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Gender</th>
<th>City</th>
</tr>
</thead>
<tbody>
<c:forEach var="ehdokas" items="${ehdokkaat}">
<tr>
<td><c:out value="${ehdokas.suku} "></c:out></td>
<td><c:out value="${ehdokas.etu} "></c:out></td>
<td><c:out value="${ehdokas.sukupuoli} "></c:out></td>
<td><c:out value="${ehdokas.kaupunki} "></c:out></td>
<form:form action="ehdokas.do" method="post">
<input type="hidden" name="id" value="${ehdokas.id }" />
<spring:message code="button.more" var="more"/>
<td><input type="submit" name="submit" class="btn btn-info" value="${more }" /></td>
</form:form>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="col-sm-2 sidenav">
<div class="well">
<p>ADS</p>
</div>
<div class="well">
<p>ADS</p>
</div>
</div>
</div>
</div>
<%# include file="/WEB-INF/views/templates/footer-bootstrap.jsp"%>
</body>
</html>
An app built from the spring petclinic sample app has added spring security with a custom login form.
The app does not have a WebMvcConfiguration.java class as suggested by this tutorial. Instead, it has the following line in mvc-core-config.xml:
<mvc:view-controller path="/login" view-name="login" />
I have done Ctrl-H in eclipse and done a key word search for the term /login in the entire workspace, but no controller is visible. I also looked in the messages-jc sample project referred to in the tutorial link above, but could not find a "/login" controller there either.
How can I add a controller that will perform spring authentication with the standard username and password, but that will also allow me to subsequently add additional code to the authentication process when the login form at the "/login" url is submitted?
Is it as simple as adding the following to SomeOtherController.java :
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String showLoginForm(Model model) {
//what goes here?
return "public/loginform";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String processLoginForm(HttpSession session, #ModelAttribute("user") User user,
BindingResult result, Model model, final RedirectAttributes redirectAttributes)
{
//what goes here?
return "secure/main";
}
In spring-security-core jar, there is an interface UserDetailsService which has a method
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
You can implement this interface and create your code your own logic, like
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) {
User user = userService.findUserByUsername(username);
if (user != null) {
String password = user.getPassword();
boolean enabled = user.getActive();
boolean accountNonExpired = user.getActive();
boolean credentialsNonExpired = user.getActive();
boolean accountNonLocked = user.getActive();
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Role r : user.getRoles()) {
authorities.add(new SimpleGrantedAuthority(r.getAuthority()));
}
org.springframework.security.core.userdetails.User securedUser = new org.springframework.security.core.userdetails.User(
username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
return securedUser;
} else {
throw new UsernameNotFoundException(
"Unable to find user with username provided!!");
}
}
and then create an object of DaoAuthenticationProvider using
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"></property>
</bean>
Finally, supply this DaoAuthenticationProvider to ProviderManager
<bean class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<list>
<ref bean="daoAuthenticationProvider" />
</list>
</constructor-arg>
</bean>
<security:authentication-manager>
<security:authentication-provider
user-service-ref="userDetailsService">
<security:password-encoder hash="plaintext"></security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
adding web.xml details
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config/spring-*.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
For this purpose you can use your own CustomAuthenticationProvider by implementing AuthenticationProvider from org.springframework.security.authentication and override public Authentication authenticate(Authentication authentication) method.
code example is given below
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
List<GrantedAuthority> grantedAuths = new ArrayList<>();
//validate and do your additionl logic and set the role type after your validation. in this code i am simply adding admin role type
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN" ));
return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
}
#Override
public boolean supports(Class<?> arg0) {
return true;
}
}
so default login handler i.e. /login(POST) will be handled by this.
Your jsp file involving login form should be like this.
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Spring security</title>
<style>
.errorblock {
color: #ff0000;
background-color: #ffEEEE;
border: 3px solid #ff0000;
padding: 8px;
margin: 16px;
}
</style>
</head>
<body onload='document.f.j_username.focus();'>
<h3>Login with Username and Password</h3>
<c:if test="${not empty error}">
<div class="errorblock">
Your login attempt was not successful, try again.
Caused :
${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
</div>
</c:if>
<%-- <c:url value="/j_spring_security_check" var="index.htm" />
<form name='f' action="${index.htm}" method='POST'> --%>
<form name='f' action="<c:url value='j_spring_security_check' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username' value=''>
</td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' />
</td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" />
</td>
</tr>
<tr>
<td colspan='2'><input name="reset" type="reset" />
</td>
</tr>
</table>
</form>
</body>
</html>
Your spring-security.xml file should look like this.
<?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:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<security:http auto-config="true" >
<security:intercept-url pattern="/index*" access="ROLE_USER" />
<security:form-login login-page="/login.htm" default-target-url="/index.htm"
authentication-failure-url="/loginerror.htm" />
<security:logout logout-success-url="/logout.htm" />
<!-- <security:csrf disabled="true"/> -->
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<!-- <security:user-service>
<security:user name="syed" password="1111" authorities="ROLE_USER" />
</security:user-service> -->
<security:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username, password, active from users where username=?"
authorities-by-username-query="select us.username, ur.authority from users us, user_roles ur
where us.user_id = ur.user_id and us.username =? "
/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
Inside the configuration element, you can restrict access to particular URLs with one or more elements. Each element specifies a URL pattern and a set of access attributes required to access the URLs. Remember that you must always include a wildcard at the end of a URL pattern. Failing to do so will make the URL pattern unable to match a URL that has request parameters.
<security:http auto-config="true" >
<security:intercept-url pattern="/index*" access="ROLE_USER" />
<security:intercept-url pattern="/Transit*" access="ROLE_USER" />
<security:form-login login-page="/login.htm" default-target-url="/index.htm"
authentication-failure-url="/loginerror.htm" />
<security:logout logout-success-url="/logout.htm" />
</security:http>
When ever we are going to describe a url without any security, Then we should remove the particular url from the above lines of code under security configured xml file. for example if we dont need any security for index page then the above coding should look like this.
<security:http auto-config="true" >
<security:intercept-url pattern="/Transit*" access="ROLE_USER" />
<security:form-login login-page="/login.htm" default-target-url="/index.htm"
authentication-failure-url="/loginerror.htm" />
<security:logout logout-success-url="/logout.htm" />
</security:http>