Add Spring Security Sample
Fixes gh-68
This commit is contained in:
22
samples/security/build.gradle
Normal file
22
samples/security/build.gradle
Normal file
@@ -0,0 +1,22 @@
|
||||
apply from: JAVA_GRADLE
|
||||
apply from: TOMCAT_GRADLE
|
||||
|
||||
tasks.findByPath("artifactoryPublish")?.enabled = false
|
||||
sonarRunner {
|
||||
skipProject = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-session-data-redis'),
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"redis.embedded:embedded-redis:0.2",
|
||||
"org.springframework.security:spring-security-config:$springSecurityVersion",
|
||||
"org.springframework.security:spring-security-web:$springSecurityVersion",
|
||||
jstlDependencies
|
||||
|
||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
|
||||
testCompile 'junit:junit:4.11'
|
||||
|
||||
integrationTestCompile gebDependencies
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package sample
|
||||
|
||||
import geb.spock.GebReportingSpec
|
||||
import pages.*
|
||||
import sample.pages.HomePage
|
||||
import sample.pages.LoginPage
|
||||
import spock.lang.Stepwise
|
||||
|
||||
/**
|
||||
* Ensures that Spring Security and Session are working
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Stepwise
|
||||
class SecurityTests extends GebReportingSpec {
|
||||
|
||||
def 'Unauthenticated user sent to log in page'() {
|
||||
when: 'unauthenticated user request protected page'
|
||||
via HomePage
|
||||
then: 'sent to the log in page'
|
||||
at LoginPage
|
||||
}
|
||||
|
||||
def 'Log in views home page'() {
|
||||
when: 'log in successfully'
|
||||
login()
|
||||
then: 'sent to original page'
|
||||
at HomePage
|
||||
and: 'the username is displayed'
|
||||
username == 'user'
|
||||
and: 'Spring Session Management is being used'
|
||||
driver.manage().cookies.find { it.name == 'SESSION' }
|
||||
and: 'Standard Session is NOT being used'
|
||||
!driver.manage().cookies.find { it.name == 'JSESSIONID' }
|
||||
}
|
||||
|
||||
def 'Log out success'() {
|
||||
when:
|
||||
logout()
|
||||
then:
|
||||
at LoginPage
|
||||
}
|
||||
|
||||
def 'Logged out user sent to log in page'() {
|
||||
when: 'logged out user request protected page'
|
||||
via HomePage
|
||||
then: 'sent to the log in page'
|
||||
at LoginPage
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package sample.pages
|
||||
|
||||
import geb.Page
|
||||
|
||||
/**
|
||||
* The home page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class HomePage extends Page {
|
||||
static url = ''
|
||||
static at = { assert driver.title == 'Secured Content'; true}
|
||||
static content = {
|
||||
username { $('#un').text() }
|
||||
logout(to:LoginPage) { $('input[type=submit]').click() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package sample.pages
|
||||
|
||||
import geb.Page
|
||||
|
||||
/**
|
||||
* The Links Page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class LoginPage extends Page {
|
||||
static url = '/login'
|
||||
static at = { assert driver.title == 'Login Page'; true}
|
||||
static content = {
|
||||
form { $('form') }
|
||||
submit { $('input[type=submit]') }
|
||||
login(required:false) { user='user', pass='password' ->
|
||||
form.username = user
|
||||
form.password = pass
|
||||
submit.click(HomePage)
|
||||
}
|
||||
}
|
||||
}
|
||||
36
samples/security/src/main/java/sample/Config.java
Normal file
36
samples/security/src/main/java/sample/Config.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package sample;
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Import(EmbeddedRedisConfiguration.class)
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
public class Config {
|
||||
|
||||
@Bean
|
||||
public JedisConnectionFactory connectionFactory() {
|
||||
return new JedisConnectionFactory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package sample;
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import redis.clients.jedis.Protocol;
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
/**
|
||||
* Runs an embedded Redis instance. This is only necessary since we do not want
|
||||
* users to have to setup a Redis instance. In a production environment, this
|
||||
* would not be used since a Redis Server would be setup.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Configuration
|
||||
public class EmbeddedRedisConfiguration {
|
||||
|
||||
@Bean
|
||||
public RedisServerBean redisServer() {
|
||||
return new RedisServerBean();
|
||||
}
|
||||
|
||||
class RedisServerBean implements InitializingBean, DisposableBean {
|
||||
private RedisServer redisServer;
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
redisServer = new RedisServer(Protocol.DEFAULT_PORT);
|
||||
redisServer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if(redisServer != null) {
|
||||
redisServer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
samples/security/src/main/java/sample/Initializer.java
Normal file
29
samples/security/src/main/java/sample/Initializer.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package sample;
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
|
||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class Initializer extends AbstractHttpSessionApplicationInitializer {
|
||||
|
||||
public Initializer() {
|
||||
super(Config.class, SecurityConfig.class);
|
||||
}
|
||||
}
|
||||
34
samples/security/src/main/java/sample/SecurityConfig.java
Normal file
34
samples/security/src/main/java/sample/SecurityConfig.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package sample;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig {
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package sample;
|
||||
|
||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||
}
|
||||
40
samples/security/src/main/java/sample/SessionServlet.java
Normal file
40
samples/security/src/main/java/sample/SessionServlet.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package sample;
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@WebServlet("/session")
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String attributeName = req.getParameter("attributeName");
|
||||
String attributeValue = req.getParameter("attributeValue");
|
||||
req.getSession().setAttribute(attributeName, attributeValue);
|
||||
resp.sendRedirect(req.getContextPath() + "/");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
}
|
||||
5
samples/security/src/main/webapp/assets/bootstrap.min.css
vendored
Normal file
5
samples/security/src/main/webapp/assets/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
32
samples/security/src/main/webapp/index.jsp
Normal file
32
samples/security/src/main/webapp/index.jsp
Normal file
@@ -0,0 +1,32 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Secured Content</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap.min.css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding: 1em;
|
||||
}
|
||||
#un {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Description</h1>
|
||||
<p>This demonstrates how Spring Session can be combined with Spring Security. The important thing to ensure is that Spring Session's Filter is included before Spring Security's Filter.</p>
|
||||
|
||||
<h1>Logged in as</h1>
|
||||
|
||||
<p>You are currently logged in as <span id="un"><c:out value="${pageContext.request.remoteUser}"/></span>.</p>
|
||||
|
||||
<c:url value="/logout" var="logoutUrl"/>
|
||||
<form action="${logoutUrl}" method="post">
|
||||
<input type="submit" value="Log Out"/>
|
||||
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +1,11 @@
|
||||
rootProject.name = 'spring-session-build'
|
||||
|
||||
include 'samples:boot'
|
||||
include 'samples:hazelcast'
|
||||
include 'samples:security'
|
||||
include 'samples:users'
|
||||
include 'samples:web'
|
||||
include 'samples:websocket'
|
||||
|
||||
include 'spring-session'
|
||||
include 'spring-session-data-redis'
|
||||
include 'samples:boot'
|
||||
include 'samples:web'
|
||||
include 'samples:users'
|
||||
include 'samples:websocket'
|
||||
include 'samples:hazelcast'
|
||||
|
||||
Reference in New Issue
Block a user