Merge pull request #38 from egmp777/master

Security Registration Code
This commit is contained in:
Eugen 2014-08-25 22:43:59 +03:00
commit 75968ea1c4
25 changed files with 195 additions and 71 deletions

View File

@ -17,16 +17,18 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<classpathentry exported="true" kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
<classpathentry exported="true" kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -26,7 +26,7 @@
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<name>org.jboss.tools.jst.web.kb.kbbuilder</name>
<arguments>
</arguments>
</buildCommand>
@ -40,6 +40,11 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
@ -50,5 +55,6 @@
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
<nature>org.hibernate.eclipse.console.hibernateNature</nature>
<nature>org.jboss.tools.jst.web.kb.kbnature</nature>
</natures>
</projectDescription>

View File

@ -7,13 +7,11 @@
<name>spring-security-login-and-registration</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.5.RELEASE</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
@ -29,9 +27,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Validation -->
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
@ -40,57 +35,47 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<!-- <scope>runtime</scope> -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<!-- <scope>runtime</scope> --> <!-- some spring dependencies need to compile against jcl -->
</dependency>
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax.inject.version}</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${javax.servlet.jsp-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Data JPA dependencies -->
<dependency>
<groupId>org.springframework.data</groupId>
@ -104,7 +89,6 @@
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- DB dependencies -->
<dependency>
<groupId>mysql</groupId>
@ -129,7 +113,6 @@
<version>${guava.version}</version>
</dependency>
</dependencies>
<build>
<finalName>spring-security-login-and-registration</finalName>
<resources>
@ -144,22 +127,16 @@
<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
<org.springframework.security.version>3.2.5.RELEASE</org.springframework.security.version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<!-- logging -->
<org.slf4j.version>1.7.6</org.slf4j.version>
<logback.version>1.1.1</logback.version>
<!-- javax jsp -->
<javax.servlet.jsp-api.version>2.3.2-b01</javax.servlet.jsp-api.version>
<!-- Inject -->
<javax.inject.version>1</javax.inject.version>
<!-- Spring Data Jpa -->
<spring-data-jpa.version>1.4.5.RELEASE</spring-data-jpa.version>
<!-- guava -->
<guava.version>17.0</guava.version>
</properties>
</project>

View File

@ -23,6 +23,7 @@ public class Role {
@JoinColumn(name = "user_id")
private User user;
@Column(name = "role")
private Integer role;

View File

@ -0,0 +1,22 @@
package org.baeldung.persistence.service;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({TYPE,ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordMatchesValidator.class)
@Documented
public @interface PasswordMatches {
String message() default "Passwords don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,16 @@
package org.baeldung.persistence.service;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
@Override
public void initialize(PasswordMatches constraintAnnotation) {
}
@Override
public boolean isValid(Object obj, ConstraintValidatorContext context){
UserDto user = (UserDto) obj;
return user.getPassword().equals(user.getMatchingPassword());
}
}

View File

@ -12,7 +12,6 @@ import org.springframework.stereotype.Service;
public class RepositoryService implements UserService {
@Autowired
private UserRepository repository;
@Autowired
private Environment env;

View File

@ -1,9 +1,24 @@
package org.baeldung.persistence.service;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;
@PasswordMatches
public class UserDto {
@NotNull
@NotEmpty
private String firstName;
@NotNull
@NotEmpty
private String lastName;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String matchingPassword;
@ValidUsername
@NotNull
@NotEmpty
private String username;
private Integer role;
@ -46,6 +61,12 @@ public class UserDto {
public void setPassword(String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(String matchingPassword) {
this.matchingPassword = matchingPassword;
}
@Override
public String toString() {

View File

@ -0,0 +1,28 @@
package org.baeldung.persistence.service;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class UsernameValidator implements ConstraintValidator<ValidUsername, String> {
private Pattern pattern;
private Matcher matcher;
private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
@Override
public void initialize(ValidUsername constraintAnnotation) {
}
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
return (validateEmail(username));
}
public boolean validateEmail(String email) {
pattern = Pattern.compile(EMAIL_PATTERN);
matcher = pattern.matcher(email);
return matcher.matches();
}
}

View File

@ -0,0 +1,24 @@
package org.baeldung.persistence.service;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ TYPE, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = UsernameValidator.class)
@Documented
public @interface ValidUsername {
String message() default "Invalid Email";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -1,7 +1,9 @@
package org.baeldung.spring;
import java.util.Locale;
import org.baeldung.persistence.service.UserValidator;
import org.baeldung.persistence.service.PasswordMatchesValidator;
import org.baeldung.persistence.service.UsernameValidator;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@ -81,11 +83,17 @@ public class MvcConfig extends WebMvcConfigurerAdapter {
messageSource.setCacheSeconds(0);
return messageSource;
}
@Bean
public UsernameValidator usernameValidator() {
UsernameValidator userNameValidator = new UsernameValidator();
return userNameValidator;
}
@Bean
public UserValidator userValidator() {
UserValidator userValidator = new UserValidator();
return userValidator;
public PasswordMatchesValidator passwordMatchesValidator() {
PasswordMatchesValidator passwordMatchesValidator = new PasswordMatchesValidator();
return passwordMatchesValidator;
}
}

View File

@ -5,16 +5,14 @@ import org.baeldung.persistence.model.User;
import org.baeldung.persistence.service.EmailExistsException;
import org.baeldung.persistence.service.UserDto;
import org.baeldung.persistence.service.UserService;
import org.baeldung.persistence.service.UserValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -23,17 +21,11 @@ import org.springframework.web.servlet.ModelAndView;
@Controller
public class RegistrationController {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
private UserService service;
@Autowired
private UserValidator validator;
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(this.validator);
}
private MessageSource messages;
@Autowired
public RegistrationController(UserService service) {
@ -50,13 +42,11 @@ public class RegistrationController {
@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto userAccountData, BindingResult result, WebRequest request, Errors errors) {
boolean goodEmailCheck = validator.validateEmail(userAccountData.getUsername());
if (!goodEmailCheck)
result.rejectValue("username", "message.badEmail");
User registered = null;
User registered = new User();
if (!result.hasErrors())
registered = createUserAccount(userAccountData, result);
if (registered == null && !userAccountData.getUsername().isEmpty() && goodEmailCheck) {
if (registered == null) {
result.rejectValue("username", "message.regError");
}
if (result.hasErrors()) {

View File

@ -8,3 +8,4 @@ init-db=false
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop

View File

@ -14,4 +14,18 @@ label.user.email=Email
label.user.firstName=First name
label.user.lastName=Last name
label.user.password=Password
label.login=Login here
label.login=Login here
ValidUsername.user.username=Invalid Username (Email)
UniqueUsername.user.username=An account with that username/email already exists
NotNull.user.firstName=First name required
NotEmpty.user.firstName=First name required
NotNull.user.lastName=Last name required
NotEmpty.user.lastName=Last name required
NotNull.user.username=Username(Email) required
NotEmpty.user.username=Username(Email) required
NotNull.user.password=Password required
NotEmpty.user.password=Password required
NotNull.user.matchingPassword=Required
NotEmpty.user.matchingPassword=Required
PasswordMatches.user:Password does not match!
Email.user.username=Invalid Username (Email)

View File

@ -14,4 +14,18 @@ label.user.email=Email
label.user.firstName=Nombre
label.user.lastName=Apellido
label.user.password=Clave
label.login=Autehtifiquese aqui
label.login=Autehtifiquese aqui
ValidUsername.user.username=Email no es valido
UniqueUsername.user.username=Ya existe una cuenta con ese nombre de usuario
NotNull.user.firstName=Por favor ingrese su nombre
NotEmpty.user.firstName=Por favor ingrese su nombre
NotNull.user.lastName=Por favor ingrese su apellido
NotEmpty.user.lastName=Por favor ingrese su apellido
NotNull.user.username=Por favor ingrese su cuenta de email
NotEmpty.user.username=Por favor ingrese su cuenta de email
NotNull.user.password=Por favor ingrese su clave
NotEmpty.user.password=Por favor ingrese su clave
NotNull.user.matchingPassword=Campo obligatirio
NotEmpty.user.matchingPassword=Campo obligatrio
PasswordMatches.user:Las claves no coinciden!
Email.user.username=Email no es valido

View File

@ -5,8 +5,6 @@
xsi:schemaLocation="
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<http use-expressions="true">
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/logout*" access="permitAll" />
@ -16,7 +14,6 @@
<intercept-url pattern="/registration*" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/invalidSession*" access="isAnonymous()" />
<!-- <intercept-url pattern="/result*" access="isAnonymous()" /> -->
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login login-page='/login.html'
authentication-failure-url="/login.html?error=true"
@ -24,13 +21,14 @@
default-target-url="/homepage.html" />
<session-management invalid-session-url="/invalidSession.html"
session-fixation-protection="none" />
<logout invalidate-session="false" logout-success-url="/logout.html?logSucc=1"
<logout invalidate-session="false" logout-success-url="/logout.html?logSucc=true"
logout-url="/j_spring_security_logout" delete-cookies="JSESSIONID" />
</http>
<beans:bean id="myAuthenticationSuccessHandler"
class="org.baeldung.security.MySimpleUrlAuthenticationSuccessHandler" />
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<!-- <password-encoder ref="passwordEncoder"/> -->
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder"

View File

@ -8,7 +8,10 @@
<head>
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
</head>
<<<<<<< HEAD
=======
>>>>>>> FETCH_HEAD
<body>
<sec:authorize ifAnyGranted="ROLE_ADMIN">
<H1>Hello Admin</H1>
@ -17,6 +20,4 @@
<a href="<c:url value="/j_spring_security_logout" />">Logout</a>
<a href="<c:url value="/home.html" />">Home</a>
</body>
</html>

View File

@ -5,20 +5,16 @@
<head>
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
</head>
<body>
<h1>This is the landing page for the admin</h1>
<security:authorize access="hasRole('ROLE_USER')">
This text is only visible to a user
<br />
</security:authorize>
<security:authorize access="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br />
</security:authorize>
<a href="<c:url value="/j_spring_security_logout" />">Logout</a>
<a href="<c:url value="/admin.html" />">Administrator Page</a>
</body>

View File

@ -6,7 +6,6 @@
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
<title>Home</title>
</head>
<body>
<h1>Welcome back home!</h1>
</body>

View File

@ -1,11 +1,15 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<<<<<<< HEAD
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
=======
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
>>>>>>> FETCH_HEAD
<%@ page session="true"%>
<html>
<head>
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
</head>
<body>
<h1>This is the homepage for the user</h1>
@ -23,5 +27,8 @@
<a href="<c:url value="/home.html" />">Home</a>
<a href="<c:url value="/admin.html" />">Administrator Page</a>
</body>
<<<<<<< HEAD
=======
>>>>>>> FETCH_HEAD
</html>

View File

@ -5,7 +5,6 @@
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
<title>Home</title>
</head>
<body>
<h1 class="alert alert-error">
<spring:message code="message.sessionExpired"></spring:message>

View File

@ -37,13 +37,11 @@
}
</script>
</head>
<body>
<h1>Login</h1>
<a href="?lang=en">English</a> |
<a href="?lang=es_ES">Spanish</a>
<form name='f' action="j_spring_security_check" method='POST' onsubmit="return validate();">
<table>
<tr>
<td>User:</td>

View File

@ -11,17 +11,16 @@
<spring:message code="message.logoutError"></spring:message>
</div>
</c:if>
<c:if test="${param.logSucc == 1}">
<div id="success">
<spring:message code="message.logoutSucc"></spring:message>
</div>
</c:if>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Logged Out</title>
</head>
<body>
<c:if test="${param.logSucc == true}">
<div id="success">
<spring:message code="message.logoutSucc"></spring:message>
</div>
</c:if>
<a href="login.html">Login</a>
</body>

View File

@ -36,6 +36,11 @@
<td><form:input path="password" value="" type="password" /></td>
<form:errors path="password" cssClass="alert alert-error" element="div" />
</tr>
<tr>
<td><label>Re-enter password:</label></td>
<td><form:input path="matchingPassword" value="" type="password"/></td>
<form:errors cssClass="alert alert-error" element="div" />
</tr>
<input type="hidden" name="role" value="1" />
<button type="submit">submit</button>
</form:form>

View File

@ -12,7 +12,6 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Registration Success</title>
</head>
<body>
<h1>
<spring:message code="message.regSucc"></spring:message>