Use xml / javaconfig folders for samples

Fixes gh-3752
This commit is contained in:
Joe Grandja
2016-04-11 10:47:06 -04:00
committed by Rob Winch
parent 2c85fb05d0
commit 945a21a3fb
543 changed files with 828 additions and 430 deletions

View File

@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-xml-tutorial</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-security-samples-xml-tutorial</name>
<description>spring-security-samples-xml-tutorial</description>
<url>http://spring.io/spring-security</url>
<organization>
<name>spring.io</name>
<url>http://spring.io/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>rwinch</id>
<name>Rob Winch</name>
<email>rwinch@gopivotal.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/spring-projects/spring-security</connection>
<developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>
<url>https://github.com/spring-projects/spring-security</url>
</scm>
<properties>
<m2eclipse.wtp.contextRoot>/sample</m2eclipse.wtp.contextRoot>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-jstlel</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,10 @@
This is the most basic sample web application for Spring Security.
If you have gradle installed, you can run the application directly from the checked out source tree, using the command
gradle jettyRun
This will start jetty on port 8080, with SSL support on port 8443.
The 'scripts' directory contains simple Unix command-line scripts for exercising the application and displaying the results.

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=peter --http-password=opal --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/listAccounts.html
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=rod --http-password=koala --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/listAccounts.html
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/listAccounts.html
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=rod --http-password=WRONG-PASSWORD --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/listAccounts.html
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=peter --http-password=opal --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/post.html?id=1\&amount=5.00
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=rod --http-password=koala --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/post.html?id=1\&amount=5.00
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/post.html?id=1\&amount=5.00
cat -n work/* | less

View File

@@ -0,0 +1,5 @@
#!/bin/bash
rm -rf work
mkdir work
wget --http-user=rod --http-password=WRONG_PASSWORD --directory-prefix=work --output-file=work/log.txt http://localhost:8080/spring-security-samples-tutorial/post.html?id=1\&amount=5.00
cat -n work/* | less

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2016 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 bigbank;
/**
* Note this class does not represent best practice, as we are failing to encapsulate
* business logic (methods) and state in the domain object. Nevertheless, this demo is
* intended to reflect what people usually do, as opposed to what they ideally would be
* doing.
*
* @author Ben Alex
*/
public class Account {
private long id = -1;
private String holder;
private double balance;
private double overdraft = 100.00;
public Account(String holder) {
this.holder = holder;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getHolder() {
return holder;
}
public void setHolder(String holder) {
this.holder = holder;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getOverdraft() {
return overdraft;
}
public void setOverdraft(double overdraft) {
this.overdraft = overdraft;
}
public String toString() {
return "Account[id=" + id + ",balance=" + balance + ",holder=" + holder
+ ", overdraft=" + overdraft + "]";
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2002-2016 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 bigbank;
public interface BankDao {
public Account readAccount(Long id);
public void createOrUpdateAccount(Account account);
public Account[] findAccounts();
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2002-2016 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 bigbank;
import java.util.HashMap;
import java.util.Map;
public class BankDaoStub implements BankDao {
private long id = 0;
private final Map<Long, Account> accounts = new HashMap<Long, Account>();
public void createOrUpdateAccount(Account account) {
if (account.getId() == -1) {
id++;
account.setId(id);
}
accounts.put(new Long(account.getId()), account);
System.out.println("SAVE: " + account);
}
public Account[] findAccounts() {
Account[] accounts = this.accounts.values().toArray(new Account[] {});
System.out.println("Returning " + accounts.length + " account(s):");
for (Account account : accounts) {
System.out.println(" > " + account);
}
return accounts;
}
public Account readAccount(Long id) {
return accounts.get(id);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2002-2016 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 bigbank;
import org.springframework.security.access.prepost.PreAuthorize;
public interface BankService {
public Account readAccount(Long id);
public Account[] findAccounts();
@PreAuthorize("hasRole('supervisor') or "
+ "hasRole('teller') and (#account.balance + #amount >= -#account.overdraft)")
public Account post(Account account, double amount);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2016 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 bigbank;
import org.springframework.util.Assert;
public class BankServiceImpl implements BankService {
private final BankDao bankDao;
public BankServiceImpl(BankDao bankDao) {
Assert.notNull(bankDao);
this.bankDao = bankDao;
}
public Account[] findAccounts() {
return this.bankDao.findAccounts();
}
public Account post(Account account, double amount) {
Assert.notNull(account);
// We read account back from DAO so it reflects the latest balance
Account a = bankDao.readAccount(account.getId());
if (a == null) {
throw new IllegalArgumentException("Couldn't find requested account");
}
a.setBalance(a.getBalance() + amount);
bankDao.createOrUpdateAccount(a);
return a;
}
public Account readAccount(Long id) {
return bankDao.readAccount(id);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2002-2016 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 bigbank;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
public class SeedData implements InitializingBean {
private BankDao bankDao;
public void afterPropertiesSet() throws Exception {
Assert.notNull(bankDao);
bankDao.createOrUpdateAccount(new Account("rod"));
bankDao.createOrUpdateAccount(new Account("dianne"));
bankDao.createOrUpdateAccount(new Account("scott"));
bankDao.createOrUpdateAccount(new Account("peter"));
}
public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2002-2016 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 bigbank.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import bigbank.BankService;
public class ListAccounts implements Controller {
private final BankService bankService;
public ListAccounts(BankService bankService) {
Assert.notNull(bankService);
this.bankService = bankService;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Security check (this is unnecessary if Spring Security is performing the
// authorization)
// if (request.getUserPrincipal() == null) {
// throw new
// AuthenticationCredentialsNotFoundException("You must login to view the account list (Spring Security message)");
// // only for Spring Security managed authentication
// }
// Actual business logic
ModelAndView mav = new ModelAndView("listAccounts");
mav.addObject("accounts", bankService.findAccounts());
return mav;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2002-2016 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 bigbank.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import bigbank.Account;
import bigbank.BankService;
public class PostAccounts implements Controller {
private final BankService bankService;
public PostAccounts(BankService bankService) {
Assert.notNull(bankService);
this.bankService = bankService;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Security check (this is unnecessary if Spring Security is performing the
// authorization)
// if (!request.isUserInRole("ROLE_TELLER")) {
// throw new
// AccessDeniedException("You must be a teller to post transactions (Spring Security message)");
// }
// Actual business logic
Long id = ServletRequestUtils.getRequiredLongParameter(request, "id");
Double amount = ServletRequestUtils.getRequiredDoubleParameter(request, "amount");
Account a = bankService.readAccount(id);
bankService.post(a, amount);
return new ModelAndView("redirect:listAccounts.html");
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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-3.0.xsd">
<bean id="bankDao" class="bigbank.BankDaoStub"/>
<bean id="seedData" class="bigbank.SeedData">
<property name="bankDao" ref="bankDao"/>
</bean>
<bean id="bankService" class="bigbank.BankServiceImpl">
<constructor-arg ref="bankDao"/>
<!-- This will add a security interceptor to the bean
<security:intercept-methods>
<security:protect method="bigbank.BankService.*" access="IS_AUTHENTICATED_REMEMBERED" />
<security:protect method="bigbank.BankService.post" access="ROLE_TELLER" />
</security:intercept-methods> -->
</bean>
</beans>

View File

@@ -0,0 +1,12 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Sample namespace-based configuration
-
-->
<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">
<debug />
<global-method-security pre-post-annotations="enabled" />
<http pattern="/static/**" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http>
<intercept-url pattern="/secure/extreme/**" access="hasAuthority('supervisor')"/>
<intercept-url pattern="/secure/**" access="authenticated" />
<!--
Allow all other requests. In a real application you should
adopt a whitelisting approach where access is not allowed by default
-->
<intercept-url pattern="/**" access="permitAll" />
<form-login />
<logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
<remember-me />
<!--
Uncomment to enable X509 client authentication support
<x509 />
-->
<!-- Uncomment to limit the number of sessions a user can have -->
<session-management invalid-session-url="/timeout.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
</http>
<!--
Usernames/Passwords are
rod/koala
dianne/emu
scott/wombat
peter/opal
-->
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder"/>
<user-service>
<user name="rod" password="$2a$10$75pBjapg4Nl8Pzd.3JRnUe7PDJmk9qBGwNEJDAlA3V.dEJxcDKn5O" authorities="supervisor, user, teller" />
<user name="dianne" password="$2a$04$bCMEyxrdF/7sgfUiUJ6Ose2vh9DAMaVBldS1Bw2fhi1jgutZrr9zm" authorities="user,teller" />
<user name="scott" password="$2a$06$eChwvzAu3TSexnC3ynw4LOSw1qiEbtNItNeYv5uI40w1i3paoSfLu" authorities="user" />
<user name="peter" password="$2a$04$8.H8bCMROLF4CIgd7IpeQ.tcBXLP5w8iplO0n.kCIkISwrIgX28Ii" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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">
<bean name="/listAccounts.html" class="bigbank.web.ListAccounts">
<constructor-arg ref="bankService"/>
</bean>
<bean name="/post.html" class="bigbank.web.PostAccounts">
<constructor-arg ref="bankService"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

View File

@@ -0,0 +1,58 @@
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Accounts</title>
</head>
<body>
<div id="content">
<h1>Accounts</h1>
<p>
Anyone can view this page, but posting to an Account requires login and must be authorized. Below are some users to try posting to Accounts with.
</p>
<ul>
<li>rod/koala - can post to any Account</li>
<li>dianne/emu - can post to Accounts as long as the balance remains above the overdraft amount</li>
<li>scott/wombat - cannot post to any Accounts</li>
</ul>
<a href="index.jsp">Home</a><br><br>
<table>
<tr>
<td><b>ID</b></td>
<td><b>Holder</b></td>
<td><b>Balance</b></td>
<td><b>Overdraft</b></td>
<td><b>Operations</b></td>
</tr>
<c:forEach var="account" items="${accounts}">
<tr>
<td>${account.id}</td>
<td>${account.holder}</td>
<td>${account.balance}</td>
<td>${account.overdraft}</td>
<td>
<a href="post.html?id=${account.id}&amp;amount=-20.00">-$20</a>
<a href="post.html?id=${account.id}&amp;amount=-5.00">-$5</a>
<a href="post.html?id=${account.id}&amp;amount=5.00">+$5</a>
<a href="post.html?id=${account.id}&amp;amount=20.00">+$20</a>
</td>
</tr>
</c:forEach>
</table>
<p>
<form action="logout" method="post">
<sec:csrfInput />
<input type="submit" value="Logout"/>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Tutorial web application
-
-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Spring Security Tutorial Application</display-name>
<!--
- Location of the XML file that defines the root application context
- Applied by ContextLoaderListener.
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext-business.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>tutorial.root</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>
<!--
- Loads the root application context of this web app at startup.
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
- Publishes events for session creation and destruction through the application
- context. Optional unless concurrent session control is being used.
-->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<!--
- Provides core MVC application controller. See bank-servlet.xml.
-->
<servlet>
<servlet-name>bank</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>bank</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@@ -0,0 +1,42 @@
<%@ page session="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Home Page</title>
</head>
<body>
<div id="content">
<h1>Home Page</h1>
<p>
Anyone can view this page.
</p>
<p>
While anyone can also view the <a href="listAccounts.html">list accounts</a> page, you must be authorized to post to an Account from the list accounts page.
</p>
<p>
Your principal object is....: <%= request.getUserPrincipal() %>
</p>
<sec:authorize url='/secure/index.jsp'>
<p>
You can currently access "/secure" URLs.
</p>
</sec:authorize>
<sec:authorize url='/secure/extreme/index.jsp'>
<p>
You can currently access "/secure/extreme" URLs.
</p>
</sec:authorize>
<p>
<a href="secure/index.jsp">Secure page</a></p>
<p><a href="secure/extreme/index.jsp">Extremely secure page</a></p>
</div>
</body>
</html>

View File

@@ -0,0 +1,20 @@
<%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Logged Out</title>
</head>
<body>
<div id="content">
<h2>Logged Out</h2>
<p>
You have been logged out. <a href="<c:url value='/'/>">Start again</a>.
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,29 @@
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Secure Page</title>
</head>
<body>
<div id="content">
<h1>VERY Secure Page</h1>
This is a protected page. You can only see me if you are a supervisor.
<sec:authorize access="hasAuthority('supervisor')">
You have authority "supervisor" (this text is surrounded by &lt;sec:authorize&gt; tags).
</sec:authorize>
<p><a href="../../">Home</a></p>
<form action="../../logout" method="post">
<sec:csrfInput />
<input type="submit" value="Logout"/>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,53 @@
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Secure Page</title>
</head>
<body>
<div id="content">
<h1>Secure Page</h1>
<p>
This is a protected page. You can get to me if you've been remembered,
or if you've authenticated this session.
</p>
<p>
<sec:authorize access="hasRole('supervisor')">
You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
</sec:authorize>
</p>
<h3>Properties obtained using &lt;sec:authentication /&gt; tag</h3>
<table border="1">
<tr><th>Tag</th><th>Value</th></tr>
<tr>
<td>&lt;sec:authentication property='name' /&gt;</td><td><sec:authentication property="name"/></td>
</tr>
<sec:authorize access="isAuthenticated()">
<tr>
<td>&lt;sec:authentication property='principal.username' /&gt;</td><td><sec:authentication property="principal.username"/></td>
</tr>
<tr>
<td>&lt;sec:authentication property='principal.enabled' /&gt;</td><td><sec:authentication property="principal.enabled"/></td>
</tr>
<tr>
<td>&lt;sec:authentication property='principal.accountNonLocked' /&gt;</td><td><sec:authentication property="principal.accountNonLocked"/></td>
</tr>
</sec:authorize>
</table>
<p><a href="../">Home</a></p>
<form action="../logout" method="post">
<sec:csrfInput />
<input type="submit" value="Logout"/>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,13 @@
body {
font-family:"Palatino Linotype","Book Antiqua",Palatino,serif;
}
#content {
margin: 5em auto;
width: 40em;
}
.securityHiddenUI, .securityHiddenUI * {
background-color: #ff4500;
}

View File

@@ -0,0 +1,20 @@
<%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Session Timeout</title>
</head>
<body>
<div id="content">
<h2>Invalid Session</h2>
<p>
Your session appears to have timed out. Please <a href="<c:url value='/'/>">start again</a>.
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
// Tutorial sample build file
apply plugin: 'war'
apply plugin: 'jetty'
war.baseName = "sample"
def excludeModules = ['spring-security-acl', 'jsr250-api', 'ehcache', 'spring-jdbc', 'spring-tx']
configurations {
excludeModules.each {name ->
runtime.exclude module: name
}
runtime.exclude group: 'org.aspectj'
}
dependencies {
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
compile project(':spring-security-core'),
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-web:$springVersion",
"org.springframework:spring-webmvc:$springVersion",
"org.slf4j:slf4j-api:$slf4jVersion"
runtime project(':spring-security-web'),
project(':spring-security-config'),
project(':spring-security-taglibs'),
jstlDependencies,
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
"ch.qos.logback:logback-core:$logbackVersion",
"ch.qos.logback:logback-classic:$logbackVersion"
}
jettyRun {
def httpConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector').newInstance()
httpConnector.port = 8080
httpConnector.confidentialPort = 8443
def httpsConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()
httpsConnector.port = 8443
httpsConnector.keystore = "$rootDir/samples/certificates/server.jks"
httpsConnector.keyPassword = 'password'
connectors = [httpConnector, httpsConnector]
}