Updated spring-security-mvc-persisted

Updated spring-security-mvc-persisted - added login error message if
unknown user, and switched default H2 database to be embedded
in-memory. Added explicit sql creation script to automatically create
table on deployment (for some reason the createTableOnStartup flag in
the jdbcTokenRepository didn’t work with embedded H2)
This commit is contained in:
corsoft 2014-05-31 16:39:21 +01:00
parent 7b7b5ae49f
commit dd020af30a
10 changed files with 141 additions and 35 deletions

View File

@ -0,0 +1,35 @@
package org.baeldung.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;
/**
* Web Controller.
*
*/
@Controller
public class MyController {
/**
* Build the view model for the login page (add authentication error
* information in the event of an unsuccessful login attempt).
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error", required = false) String error) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("message",
"Username or password not recognised - please try again.");
}
model.setViewName("login");
return model;
}
}

View File

@ -54,10 +54,10 @@ public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSu
boolean isAdmin = false;
final Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (final GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
if (grantedAuthority.getAuthority().equals(SecurityRole.ROLE_USER.toString())) {
isUser = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
} else if (grantedAuthority.getAuthority().equals(SecurityRole.ROLE_ADMIN.toString())) {
isAdmin = true;
break;
}

View File

@ -0,0 +1,12 @@
package org.baeldung.security;
/**
* Simple enum of Security Roles available.
*
*/
public enum SecurityRole {
ROLE_USER,
ROLE_ADMIN;
}

View File

@ -8,6 +8,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.baeldung.security.SecurityRole;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
@ -28,10 +29,8 @@ public class MyUserDetailsService implements UserDetailsService {
public MyUserDetailsService() {
availableUsers.put("user",
createUser("user", "password", Arrays.asList("ROLE_USER")));
availableUsers.put("admin",
createUser("admin", "password", Arrays.asList("ROLE_ADMIN")));
populateDemoUsers();
}
@Override
@ -49,13 +48,39 @@ public class MyUserDetailsService implements UserDetailsService {
}
private User createUser(String username, String password, List<String> roles) {
/**
* Create demo users (note: obviously in a real system these would be persisted
* in database or retrieved from another system).
*/
private void populateDemoUsers(){
logger.info("Populate demo users");
availableUsers.put("user",
createUser("user", "password", Arrays.asList(SecurityRole.ROLE_USER)));
availableUsers.put("admin",
createUser("admin", "password", Arrays.asList(SecurityRole.ROLE_ADMIN)));
}
/**
* Create a demo User.
*
* @param username
* Username
* @param password
* Password
* @param roles
* Role names user is assigned to
* @return User
*/
private User createUser(String username, String password, List<SecurityRole> roles) {
logger.info("Create user " + username);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
for (SecurityRole role : roles) {
authorities.add(new SimpleGrantedAuthority(role.toString()));
}
return new User(username, password, true, true, true, true, authorities);
}

View File

@ -1,9 +1,11 @@
package org.baeldung.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
/**
* Spring Security Configuration.
@ -13,8 +15,13 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@ImportResource({ "classpath:webSecurityConfig.xml" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationSuccessHandler mySimpleUrlAuthenticationSuccessHandler;
public SecurityConfig() {
super();
}
}

View File

@ -0,0 +1,7 @@
-- SQL example for H2 (ran automatically by the spring config for the embedded H2 example)
create table if not exists persistent_logins (
username varchar_ignorecase(100) not null,
series varchar(64) primary key,
token varchar(64) not null,
last_used timestamp not null
);

View File

@ -1,11 +1,10 @@
# jdbc.X
# Jdbc H2 configuration
# By default uses the embedded in memory database
# Option provided to use the tcp version if you want to start H2 service and view data
# Chosen database defined in DatabaseConfig.java
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:tcp://localhost/~/test
#jdbc.url=jdbc:h2:tcp://localhost/~/testDb
jdbc.url=jdbc:h2:mem:test;MVCC=TRUE
jdbc.user=sa
jdbc.pass=
# hibernate.X
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop

View File

@ -1,11 +1,7 @@
# jdbc.X
# Jdbc PostgreSQL option
# Chosen database defined in DatabaseConfig.java
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432
jdbc.user=postgres
jdbc.pass=
# hibernate.X
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop

View File

@ -5,11 +5,13 @@
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
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://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">
<http use-expressions="true">
@ -25,28 +27,29 @@
<remember-me data-source-ref="dataSource" token-validity-seconds="86400"/>
</http>
<!-- create H2 embedded database table on startup -->
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:/persisted_logins_create_table.sql"/>
</jdbc:embedded-database>
<!-- Persistent Remember Me Service -->
<beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:property name="key" value="myAppKey" />
<beans:property name="tokenRepository" ref="jdbcTokenRepository" />
<beans:property name="userDetailsService" ref="myUserDetailsService" />
</beans:bean>
<!-- Uses a database table to maintain a set of persistent login data -->
<!-- Uses a database table to maintain a set of persistent login data -->
<beans:bean id="jdbcTokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<beans:property name="createTableOnStartup" value="false" />
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- Authentication Manager (uses same UserDetailsService as RememberMeService)-->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>
</authentication-manager>
</authentication-manager>
</beans:beans>

View File

@ -1,5 +1,18 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<head>
<style>
.message{
margin-top: 20px;
padding: 10px;
color:#FF0000;
border: 1px solid;
border-radius: 2px;
background-color: #F5F6CE;
border-color: #FF0000;
}
</style>
</head>
<body>
<h1>Login</h1>
@ -23,8 +36,17 @@
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
<c:if test="${not empty message}">
<div class="message">${message}</div>
</c:if>
</body>
</html>