SEC-2444: Convert Java Config samples to thymeleaf and tiles
|
@ -19,3 +19,4 @@ build/
|
|||
*.iws
|
||||
.gradle/
|
||||
atlassian-ide-plugin.xml
|
||||
/samples
|
||||
|
|
|
@ -31,6 +31,7 @@ allprojects {
|
|||
group = 'org.springframework.security'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
maven { url "http://repo.terracotta.org/maven2/" }
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ The next step is to create a Spring Security configuration.
|
|||
----
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.security.config.annotation.authentication.builders.*;
|
||||
import org.springframework.security.config.annotation.web.configuration.*;
|
||||
|
|
|
@ -150,65 +150,48 @@ public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
|
|||
registry.addViewController("/login").setViewName("login");
|
||||
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InternalResourceViewResolver jspxViewResolver() {
|
||||
InternalResourceViewResolver result = new InternalResourceViewResolver();
|
||||
result.setPrefix("/WEB-INF/views/");
|
||||
result.setSuffix(".jspx");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
== Creating a login view
|
||||
|
||||
Our existing configuration means that all we need to do is create a *login.jspx* file with the following contents:
|
||||
Our existing configuration means that all we need to do is create a *login.html* file with the following contents:
|
||||
|
||||
.src/main/webapp/WEB-INF/views/login.jspx
|
||||
.src/main/resources/views/login.html
|
||||
[source,xml]
|
||||
----
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Please Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<c:url value="/login" var="loginUrl"/>
|
||||
<form:form name="f" action="${loginUrl}" method="post"> <1>
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<c:if test="${param.error != null}"> <2>
|
||||
<div class="alert alert-error">
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Create</title>
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<form name="f" th:action="@{/login}" method="post"> <1>
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<div th:if="${param.error}" class="alert alert-error"> <2>
|
||||
Invalid username and password.
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${param.logout != null}"> <3>
|
||||
<div class="alert alert-success">
|
||||
<div th:if="${param.logout}" class="alert alert-success"> <3>
|
||||
You have been logged out.
|
||||
</div>
|
||||
</c:if>
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username"/> <4>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password"/> <5>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form:form>
|
||||
</body>
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username"/> <4>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password"/> <5>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
||||
----
|
||||
|
||||
<1> The URL we submit our username and password to is the same URL as our login form (i.e. */login*), but a *POST* instead of a *GET*.
|
||||
<2> When authentication fails, the browser is redirected to */login?error* so we can display an error message by detecting if the parameter *error* is non-null.
|
||||
<3> When we are successfully loged out, the browser is redirected to */login?logout* so we can display an logout success message by detecting if the parameter *logout* is non-null.
|
||||
<3> When we are successfully logged out, the browser is redirected to */login?logout* so we can display an logout success message by detecting if the parameter *logout* is non-null.
|
||||
<4> The username should be present on the HTTP parameter username
|
||||
<5> The password should be present on the HTTP parameter password
|
||||
|
||||
|
|
|
@ -34,16 +34,14 @@ We have created the Spring Security configuration, but we still need to register
|
|||
----
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.core.annotation.*;
|
||||
import org.springframework.security.web.context.*;
|
||||
|
||||
@Order(2)
|
||||
public class MessageSecurityWebApplicationInitializer
|
||||
extends AbstractSecurityWebApplicationInitializer {
|
||||
}
|
||||
----
|
||||
|
||||
The `MessageSecurityWebApplicationInitializer` will automatically register the springSecurityFilterChain Filter for every URL in your application. We add `@Order(2)` so the springSecurityFilterChain is inserted before our Sitemesh Filter declared in <<message-web-application-inititializer-java, MessageWebApplicationInitializer.java>>
|
||||
The `MessageSecurityWebApplicationInitializer` will automatically register the springSecurityFilterChain Filter for every URL in your application. If Filters are added within other `WebApplicationInitializer` instances we can use `@Order` to control the ordering of the Filter instances.
|
||||
|
||||
=== Verify SecurityConfig is loaded
|
||||
|
||||
|
@ -53,7 +51,6 @@ Just because <<security-config-java,SecurityConfig>> exists, does not mean that
|
|||
.MessageWebApplicationInitializer.java
|
||||
[source,java]
|
||||
----
|
||||
@Order(1)
|
||||
public class MessageWebApplicationInitializer extends
|
||||
AbstractAnnotationConfigDispatcherServletInitializer {
|
||||
|
||||
|
@ -86,64 +83,39 @@ include::{hello-include-dir}/exploring-the-secured-application.asc[]
|
|||
|
||||
==== Displaying the user name
|
||||
|
||||
Now that we have authenticated, let's update the application to display the username if the user is authenticated. Update main.jsp to contain the following snippet:
|
||||
Now that we have authenticated, let's see how our application is displaying the username if the user is authenticated.
|
||||
|
||||
.src/main/webapp/WEB-INF/decorators/main.jsp
|
||||
.messages-jc/src/main/resources/views/layout.html
|
||||
[source,html]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<div class="nav-collapse collapse">
|
||||
*<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
<div th:if="${#httpServletRequest.remoteUser != null}">
|
||||
<p th:text="${#httpServletRequest.remoteUser}">
|
||||
sample_user
|
||||
</p>
|
||||
</c:if>*
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
----
|
||||
|
||||
WARNING: The `<c:out />` tag ensures the username is escaped to avoid http://en.wikipedia.org/wiki/Cross-site_scripting[XSS vulnerabilities] Regardless of how an application renders user inputed values, it should ensure that the values are properly escaped.
|
||||
In our samples we use http://www.thymeleaf.org/[Thymeleaf], but any view technology will work. The point is to check the HttpServletRequest#getRemoteUser() method for the current user. This works because Spring Security integrates with the <<servlet-api-integration,Servlet API methods>>. Specifically, it is integrating with `HttpServletRequest#getRemoteUser()`.
|
||||
|
||||
Refresh the page at http://localhost:8080/sample/ and you will see the user name displayed. This works because Spring Security integrates with the <<servlet-api-integration,Servlet API methods>>. Specifically, it is integrating with `HttpServletRequest#getRemoteUser()`.
|
||||
WARNING: The Thymeleaf ensures the username is escaped to avoid http://en.wikipedia.org/wiki/Cross-site_scripting[XSS vulnerabilities] Regardless of how an application renders user inputed values, it should ensure that the values are properly escaped.
|
||||
|
||||
==== Logging out
|
||||
|
||||
Now that we can view the user name, let's update the application to allow logging out. Update the body of index.jsp to contain a log out link as shown below:
|
||||
We can view the user name, but how are we able to log out? Below you can see how we are able to log out.
|
||||
|
||||
.src/main/webapp/index.jsp
|
||||
.messages-jc/src/main/resources/views/layout.html
|
||||
[source,html]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
*<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post">
|
||||
<input type="submit" value="Log out" />
|
||||
</form:form>*
|
||||
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form th:action="@{/logout}" method="post">
|
||||
<input type="submit" value="Log out" />
|
||||
</form>
|
||||
----
|
||||
In order to help protect against http://en.wikipedia.org/wiki/Cross-site_request_forgery[CSRF attacks], by default, Spring Security Java Configuration log out requires:
|
||||
|
||||
* the HTTP method must be a POST
|
||||
* the CSRF token must be added to the request. Since we are using Spring MVC, the CSRF token is automatically added as a hidden input for you (view the source to see it). If you were not using Spring MVC, you can access the CsrfToken on the ServletRequest using the attribute _csrf
|
||||
* the CSRF token must be added to the request. Since we are using Thymeleaf, the CSRF token is automatically added as a hidden input for you (view the source to see it). If you were not using Spring MVC or Thymeleaf, you can access the CsrfToken on the ServletRequest using the attribute _csrf
|
||||
|
||||
Refresh the page at http://localhost:8080/sample/ and you will see the log out button. Click the button and see that the application logs you out successfully.
|
||||
Click the button and see that the application logs you out successfully.
|
||||
|
||||
== Conclusion
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ ext.seleniumVersion = '2.33.0'
|
|||
ext.groovyVersion = '2.0.5'
|
||||
ext.spockVersion = '0.7-groovy-2.0'
|
||||
ext.gebVersion = '0.9.0'
|
||||
ext.thymeleafVersion = '2.1.2.RELEASE'
|
||||
|
||||
ext.powerMockDependencies = [
|
||||
"org.powermock:powermock-core:$powerMockVersion",
|
||||
|
|
|
@ -16,11 +16,18 @@
|
|||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
||||
|
||||
/**
|
||||
* No customizations of {@link AbstractSecurityWebApplicationInitializer} are necessary.
|
||||
* We customize {@link AbstractSecurityWebApplicationInitializer} to enable the
|
||||
* {@link HttpSessionEventPublisher}.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||
|
||||
@Override
|
||||
protected boolean enableHttpSessionEventPublisher() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
|
@ -13,20 +12,12 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
|||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled=true)
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web
|
||||
.ignoring()
|
||||
.antMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void registerGlobalAuthentication(
|
||||
AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER").and()
|
||||
.withUser("admin").password("password").roles("USER", "ADMIN");
|
||||
.withUser("user").password("password").roles("USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,12 +25,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/users**","/sessions/**").hasRole("ADMIN")
|
||||
.antMatchers("/resources/**","/signup").permitAll()
|
||||
.anyRequest().hasRole("USER")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.permitAll()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.maximumSessions(1)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,39 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Please Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<c:url value="/login" var="loginUrl"/>
|
||||
<form name="f" action="${loginUrl}" method="post">
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<c:if test="${param.error != null}">
|
||||
<div class="alert alert-error">
|
||||
Failed to login.
|
||||
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
|
||||
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
|
||||
</c:if>
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${param.logout != null}">
|
||||
<div class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
</c:if>
|
||||
<label for="j_username">Username</label>
|
||||
<input type="text" id="j_username" name="username" value="${username}"/>
|
||||
<label for="j_password">Password</label>
|
||||
<input type="password" id="j_password" name="password"/>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,26 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Compose</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form:form action="./" method="post" modelAttribute="message">
|
||||
<form:errors path="*" element="div" cssClass="alert alert-error" />
|
||||
<label for="summary">Summary</label>
|
||||
<form:input type="text" path="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<form:textarea path="text" class="input-xxlarge"></form:textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" />
|
||||
</div>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,40 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Inbox</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${empty messages}">
|
||||
<tr>
|
||||
<td colspan="2" class="msg">You have not received any mail yet.</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${messages}" var="message">
|
||||
<tr>
|
||||
<td><fmt:formatDate value="${message.created.time}"/></td>
|
||||
<spring:url var="messageUrl" value="/{id}">
|
||||
<spring:param name="id" value="${message.id}"/>
|
||||
</spring:url>
|
||||
<td><a href="${messageUrl}"><c:out value="${message.summary}"/></a></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,24 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title><c:out value="${message.summary}"/></title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Message : <c:out value="${message.summary}"/></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd><fmt:formatDate value="${message.created.time}"/></dd>
|
||||
<dt>Message</dt>
|
||||
<dd><c:out value="${message.text}"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Create</title>
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<form name="f" th:action="@{/login}" method="post">
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<div th:if="${param.error}" class="alert alert-error">
|
||||
Invalid username and password.
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username"/>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password"/>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.springframework.security.samples.config;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
|
||||
|
||||
/**
|
||||
|
@ -23,6 +22,5 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
|
|||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Order(2)
|
||||
public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/disabled</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,149 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<meta name="_csrf" content="${_csrf.token}"/>
|
||||
<meta name="_csrf_header" content="${_csrf.headerName}"/>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a data-bind="click: $root.goToInbox" href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a data-bind="click: $root.goToCompose" href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<spring:url value="/resources/js/jquery-1.8.3.js" var="jqueryUrl" />
|
||||
<script type="text/javascript" src="${jqueryUrl}"><!-- --></script>
|
||||
<spring:url value="/resources/js/knockout-2.3.0.js" var="knockoutUrl" />
|
||||
<script type="text/javascript" src="${knockoutUrl}"><!-- --></script>
|
||||
<spring:url value="/resources/js/message.js" var="messageUrl" />
|
||||
<script type="text/javascript" src="${messageUrl}"><!-- --></script>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,184 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail</title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<meta name="_csrf" content="${_csrf.token}"/>
|
||||
<meta name="_csrf_header" content="${_csrf.headerName}"/>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a data-bind="click: $root.goToInbox" href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a data-bind="click: $root.goToCompose" href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<div data-bind="with: inbox">
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach: $root.messages">
|
||||
<tr data-bind="click: $root.goToMessage">
|
||||
<td data-bind="text: created"></td>
|
||||
<td><a data-bind="text: summary, attr: { href: id}"></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="container" data-bind="with: chosenMessageData">
|
||||
<h1>Message : <span data-bind="text: summary"></span></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd data-bind="text: created"></dd>
|
||||
<dt>Message</dt>
|
||||
<dd data-bind="html: text"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="container" data-bind="with: compose">
|
||||
<h1>Messages : Create</h1>
|
||||
<div class="alert alert-error" data-bind="foreach: $root.errors, visible: $root.errors().length">
|
||||
<li data-bind="text: $data"></li>
|
||||
</div>
|
||||
<form action="./" method="post">
|
||||
<label for="summary">Summary</label>
|
||||
<input type="text" id="summary" data-bind="value: summary" name="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<textarea name="text" id="text" data-bind="value: text" class="input-xxlarge"><!-- --></textarea>
|
||||
<div class="form-actions">
|
||||
<input type="button" data-bind="click: $root.save" value="Create" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<c:url value="/resources/js/jquery-1.8.3.js" var="jqueryUrl" />
|
||||
<script type="text/javascript" src="${jqueryUrl}"><!-- --></script>
|
||||
<c:url value="/resources/js/knockout-2.3.0.js" var="knockoutUrl" />
|
||||
<script type="text/javascript" src="${knockoutUrl}"><!-- --></script>
|
||||
<c:url value="/resources/js/message.js" var="messageUrl" />
|
||||
<script type="text/javascript" src="${messageUrl}"><!-- --></script>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,26 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Compose</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form:form action="./" method="post" modelAttribute="message">
|
||||
<form:errors path="*" element="div" cssClass="alert alert-error" />
|
||||
<label for="summary">Summary</label>
|
||||
<form:input type="text" path="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<form:textarea path="text" class="input-xxlarge"></form:textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" />
|
||||
</div>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,40 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Inbox</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${empty messages}">
|
||||
<tr>
|
||||
<td colspan="2" class="msg">You have not received any mail yet.</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${messages}" var="message">
|
||||
<tr>
|
||||
<td><fmt:formatDate value="${message.created.time}"/></td>
|
||||
<spring:url var="messageUrl" value="/{id}">
|
||||
<spring:param name="id" value="${message.id}"/>
|
||||
</spring:url>
|
||||
<td><a href="${messageUrl}"><c:out value="${message.summary}"/></a></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,24 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title><c:out value="${message.summary}"/></title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Message : <c:out value="${message.summary}"/></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd><fmt:formatDate value="${message.created.time}"/></dd>
|
||||
<dt>Message</dt>
|
||||
<dd><c:out value="${message.text}"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -3,7 +3,6 @@ package org.springframework.security.samples.config;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
|
@ -16,18 +15,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER");
|
||||
.withUser("user").password("password").roles("USER").and()
|
||||
.withUser("admin").password("password").roles("USER","ADMIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/resources/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,39 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Please Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<c:url value="/login" var="loginUrl"/>
|
||||
<form name="f" action="${loginUrl}" method="post">
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<c:if test="${param.error != null}">
|
||||
<div class="alert alert-error">
|
||||
Failed to login.
|
||||
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
|
||||
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
|
||||
</c:if>
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${param.logout != null}">
|
||||
<div class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
</c:if>
|
||||
<label for="j_username">Username</label>
|
||||
<input type="text" id="j_username" name="username" value="${username}"/>
|
||||
<label for="j_password">Password</label>
|
||||
<input type="password" id="j_password" name="password"/>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,26 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Compose</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form:form action="./" method="post" modelAttribute="message">
|
||||
<form:errors path="*" element="div" cssClass="alert alert-error" />
|
||||
<label for="summary">Summary</label>
|
||||
<form:input type="text" path="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<form:textarea path="text" class="input-xxlarge"></form:textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" />
|
||||
</div>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,40 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Inbox</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${empty messages}">
|
||||
<tr>
|
||||
<td colspan="2" class="msg">You have not received any mail yet.</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${messages}" var="message">
|
||||
<tr>
|
||||
<td><fmt:formatDate value="${message.created.time}"/></td>
|
||||
<spring:url var="messageUrl" value="/{id}">
|
||||
<spring:param name="id" value="${message.id}"/>
|
||||
</spring:url>
|
||||
<td><a href="${messageUrl}"><c:out value="${message.summary}"/></a></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,24 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title><c:out value="${message.summary}"/></title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Message : <c:out value="${message.summary}"/></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd><fmt:formatDate value="${message.created.time}"/></dd>
|
||||
<dt>Message</dt>
|
||||
<dd><c:out value="${message.text}"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -6,7 +6,6 @@ import javax.sql.DataSource;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
|
@ -24,16 +23,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
.withDefaultSchema()
|
||||
.withUser("user").password("password").roles("USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/resources/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,39 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Please Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<c:url value="/login" var="loginUrl"/>
|
||||
<form name="f" action="${loginUrl}" method="post">
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<c:if test="${param.error != null}">
|
||||
<div class="alert alert-error">
|
||||
Failed to login.
|
||||
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
|
||||
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
|
||||
</c:if>
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${param.logout != null}">
|
||||
<div class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
</c:if>
|
||||
<label for="j_username">Username</label>
|
||||
<input type="text" id="j_username" name="username" value="${username}"/>
|
||||
<label for="j_password">Password</label>
|
||||
<input type="password" id="j_password" name="password"/>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,26 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Compose</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form:form action="./" method="post" modelAttribute="message">
|
||||
<form:errors path="*" element="div" cssClass="alert alert-error" />
|
||||
<label for="summary">Summary</label>
|
||||
<form:input type="text" path="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<form:textarea path="text" class="input-xxlarge"></form:textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" />
|
||||
</div>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,40 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Inbox</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${empty messages}">
|
||||
<tr>
|
||||
<td colspan="2" class="msg">You have not received any mail yet.</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${messages}" var="message">
|
||||
<tr>
|
||||
<td><fmt:formatDate value="${message.created.time}"/></td>
|
||||
<spring:url var="messageUrl" value="/{id}">
|
||||
<spring:param name="id" value="${message.id}"/>
|
||||
</spring:url>
|
||||
<td><a href="${messageUrl}"><c:out value="${message.summary}"/></a></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,24 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title><c:out value="${message.summary}"/></title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Message : <c:out value="${message.summary}"/></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd><fmt:formatDate value="${message.created.time}"/></dd>
|
||||
<dt>Message</dt>
|
||||
<dd><c:out value="${message.text}"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -3,7 +3,6 @@ package org.springframework.security.samples.config;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
|
@ -18,16 +17,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
.userDnPatterns("uid={0},ou=people")
|
||||
.groupSearchBase("ou=groups");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/resources/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<decorators defaultdir="/WEB-INF/decorators">
|
||||
<decorator name="main" page="main.jsp">
|
||||
<pattern>/*</pattern>
|
||||
</decorator>
|
||||
</decorators>
|
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
|
||||
xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator"
|
||||
xmlns:page="http://www.opensymphony.com/sitemesh/page"
|
||||
xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:sec="http://www.springframework.org/security/tags"
|
||||
xmlns:tags="urn:jsptagdir:/WEB-INF/tags" version="2.0">
|
||||
|
||||
<jsp:directive.page contentType="text/html" pageEncoding="UTF-8" />
|
||||
<jsp:output omit-xml-declaration="true" />
|
||||
<jsp:output doctype-root-element="HTML"
|
||||
doctype-system="about:legacy-compat" />
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>SecureMail: <decorator:title/></title>
|
||||
<c:url var="faviconUrl" value="/resources/img/favicon.ico"/>
|
||||
<link rel="icon" type="image/x-icon" href="${faviconUrl}"/>
|
||||
<c:url var="bootstrapUrl" value="/resources/css/bootstrap.css"/>
|
||||
<link href="${bootstrapUrl}" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<c:url var="bootstrapResponsiveUrl" value="/resources/css/bootstrap-responsive.css"/>
|
||||
<link href="${bootstrapResponsiveUrl}" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<c:url var="homeUrl" value="/"/>
|
||||
<c:url var="logoUrl" value="/resources/img/logo.png"/>
|
||||
<a class="brand" href="${homeUrl}"><img src="${logoUrl}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<c:if test="${pageContext.request.remoteUser != null}">
|
||||
<c:url var="logoutUrl" value="/logout"/>
|
||||
<form:form class="navbar-form pull-right" action="${logoutUrl}" method="post"><input type="submit" value="Log out" /></form:form>
|
||||
<p class="navbar-text pull-right">
|
||||
<c:out value="${pageContext.request.remoteUser}"/>
|
||||
</p>
|
||||
</c:if>
|
||||
<ul class="nav">
|
||||
<c:url var="inboxUrl" value="/"/>
|
||||
<li><a href="${inboxUrl}">Inbox</a></li>
|
||||
<c:url var="composeUrl" value="/?form"/>
|
||||
<li><a href="${composeUrl}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<decorator:body/>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,39 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Please Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<c:url value="/login" var="loginUrl"/>
|
||||
<form name="f" action="${loginUrl}" method="post">
|
||||
<fieldset>
|
||||
<legend>Please Login</legend>
|
||||
<c:if test="${param.error != null}">
|
||||
<div class="alert alert-error">
|
||||
Failed to login.
|
||||
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
|
||||
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
|
||||
</c:if>
|
||||
</div>
|
||||
</c:if>
|
||||
<c:if test="${param.logout != null}">
|
||||
<div class="alert alert-success">
|
||||
You have been logged out.
|
||||
</div>
|
||||
</c:if>
|
||||
<label for="j_username">Username</label>
|
||||
<input type="text" id="j_username" name="username" value="${username}"/>
|
||||
<label for="j_password">Password</label>
|
||||
<input type="password" id="j_password" name="password"/>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn">Log in</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,26 +0,0 @@
|
|||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core"
|
||||
xmlns:form="http://www.springframework.org/tags/form" version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Compose</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form:form action="./" method="post" modelAttribute="message">
|
||||
<form:errors path="*" element="div" cssClass="alert alert-error" />
|
||||
<label for="summary">Summary</label>
|
||||
<form:input type="text" path="summary" class="input-xxlarge" />
|
||||
<label for="text">Message</label>
|
||||
<form:textarea path="text" class="input-xxlarge"></form:textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" />
|
||||
</div>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,40 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Inbox</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inbox</h1>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:if test="${empty messages}">
|
||||
<tr>
|
||||
<td colspan="2" class="msg">You have not received any mail yet.</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
<c:forEach items="${messages}" var="message">
|
||||
<tr>
|
||||
<td><fmt:formatDate value="${message.created.time}"/></td>
|
||||
<spring:url var="messageUrl" value="/{id}">
|
||||
<spring:param name="id" value="${message.id}"/>
|
||||
</spring:url>
|
||||
<td><a href="${messageUrl}"><c:out value="${message.summary}"/></a></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
|
@ -1,24 +0,0 @@
|
|||
<jsp:root
|
||||
xmlns:jsp="http://java.sun.com/JSP/Page"
|
||||
xmlns:spring="http://www.springframework.org/tags"
|
||||
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
|
||||
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:form="http://www.springframework.org/tags/form"
|
||||
version="2.0">
|
||||
<jsp:directive.page language="java" contentType="text/html"/>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title><c:out value="${message.summary}"/></title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Message : <c:out value="${message.summary}"/></h1>
|
||||
<dl>
|
||||
<dt>Created</dt>
|
||||
<dd><fmt:formatDate value="${message.created.time}"/></dd>
|
||||
<dt>Message</dt>
|
||||
<dd><c:out value="${message.text}"/></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -9,7 +9,6 @@ dependencies {
|
|||
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
||||
"org.hibernate:hibernate-entitymanager:3.6.10.Final",
|
||||
"org.hsqldb:hsqldb:2.2.8",
|
||||
"opensymphony:sitemesh:2.4.2",
|
||||
"javax.validation:validation-api:1.0.0.GA",
|
||||
"org.hibernate:hibernate-validator:4.2.0.Final",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
|
@ -21,5 +20,7 @@ dependencies {
|
|||
"org.springframework:spring-instrument:$springVersion",
|
||||
"org.springframework:spring-core:$springVersion",
|
||||
"org.springframework:spring-aspects:$springVersion",
|
||||
"org.springframework.data:spring-data-jpa:1.3.4.RELEASE"
|
||||
"org.springframework.data:spring-data-jpa:1.3.4.RELEASE",
|
||||
"org.thymeleaf:thymeleaf-spring3:$thymeleafVersion",
|
||||
"org.thymeleaf.extras:thymeleaf-extras-tiles2:2.1.0.RELEASE"
|
||||
}
|
||||
|
|
|
@ -55,12 +55,6 @@
|
|||
<version>1.0.0.GA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>opensymphony</groupId>
|
||||
<artifactId>sitemesh</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
|
@ -169,6 +163,18 @@
|
|||
<version>3.2.6.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-tiles2</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring3</artifactId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
|
|
|
@ -2,13 +2,10 @@ package org.springframework.security.samples.config;
|
|||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.samples.mvc.config.WebMvcConfiguration;
|
||||
import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
|
||||
|
||||
import com.opensymphony.sitemesh.webapp.SiteMeshFilter;
|
||||
|
||||
@Order(1)
|
||||
public class MessageWebApplicationInitializer extends
|
||||
AbstractAnnotationConfigDispatcherServletInitializer {
|
||||
|
||||
|
@ -29,6 +26,6 @@ public class MessageWebApplicationInitializer extends
|
|||
|
||||
@Override
|
||||
protected Filter[] getServletFilters() {
|
||||
return new Filter[] { new SiteMeshFilter() };
|
||||
return new Filter[] { new HiddenHttpMethodFilter() };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,13 @@ public class MessageController {
|
|||
return new ModelAndView("messages/show", "message", message);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "{id}", method=RequestMethod.DELETE)
|
||||
public String delete(@PathVariable("id") Message message, RedirectAttributes redirect) {
|
||||
messageRepository.delete(message);
|
||||
redirect.addFlashAttribute("globalMessage", "Message removed successfully");
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
@RequestMapping(params="form", method=RequestMethod.GET)
|
||||
public String createForm(@ModelAttribute Message message) {
|
||||
return "messages/compose";
|
||||
|
|
|
@ -10,7 +10,12 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.thymeleaf.extras.tiles2.dialect.TilesDialect;
|
||||
import org.thymeleaf.extras.tiles2.spring.web.configurer.ThymeleafTilesConfigurer;
|
||||
import org.thymeleaf.extras.tiles2.spring.web.view.ThymeleafTilesView;
|
||||
import org.thymeleaf.spring3.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring3.view.ThymeleafViewResolver;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
|
||||
@EnableWebMvc
|
||||
@ComponentScan("org.springframework.security.samples.mvc")
|
||||
|
@ -27,18 +32,42 @@ public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
|
|||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(31556926);
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/").setCachePeriod(31556926);
|
||||
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InternalResourceViewResolver jspxViewResolver() {
|
||||
InternalResourceViewResolver result = new InternalResourceViewResolver();
|
||||
result.setPrefix("/WEB-INF/views/");
|
||||
result.setSuffix(".jspx");
|
||||
public ClassLoaderTemplateResolver templateResolver() {
|
||||
ClassLoaderTemplateResolver result = new ClassLoaderTemplateResolver();
|
||||
result.setPrefix("views/");
|
||||
result.setSuffix(".html");
|
||||
result.setTemplateMode("HTML5");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ThymeleafTilesConfigurer tilesConfigurer() {
|
||||
ThymeleafTilesConfigurer tilesConfigurer = new ThymeleafTilesConfigurer();
|
||||
tilesConfigurer.setDefinitions(new String[] { "classpath:tiles/tiles-def.xml"});
|
||||
return tilesConfigurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringTemplateEngine templateEngine(ClassLoaderTemplateResolver templateResolver) {
|
||||
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
|
||||
templateEngine.setTemplateResolver(templateResolver);
|
||||
templateEngine.addDialect(new TilesDialect());
|
||||
return templateEngine;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) {
|
||||
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
|
||||
viewResolver.setTemplateEngine(templateEngine);
|
||||
viewResolver.setViewClass(ThymeleafTilesView.class);
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DomainClassConverter<?> domainClassConverter() {
|
||||
return new DomainClassConverter<FormattingConversionService>(mvcConversionService);
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE tiles-definitions PUBLIC
|
||||
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
|
||||
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
|
||||
<tiles-definitions>
|
||||
|
||||
<definition name="messages/*"
|
||||
template="layout">
|
||||
<put-attribute name="content"
|
||||
value="content/messages/{1}"/>
|
||||
<put-attribute name="title"
|
||||
value="title/messages/{1}"/>
|
||||
<put-attribute name="head"
|
||||
value="head/messages/{1}"/>
|
||||
</definition>
|
||||
|
||||
<definition name="content/messages/*"
|
||||
template="messages/{1} :: content"/>
|
||||
<definition name="title/messages/*"
|
||||
template="messages/{1} :: title"/>
|
||||
<definition name="head/messages/*"
|
||||
template="messages/{1} :: /html/head/link"/>
|
||||
|
||||
<definition name="user/*"
|
||||
template="layout">
|
||||
<put-attribute name="content"
|
||||
value="content/user/{1}"/>
|
||||
<put-attribute name="title"
|
||||
value="title/user/{1}"/>
|
||||
<put-attribute name="head"
|
||||
value="head/user/{1}"/>
|
||||
</definition>
|
||||
|
||||
<definition name="content/user/*"
|
||||
template="user/{1} :: content"/>
|
||||
<definition name="title/user/*"
|
||||
template="user/{1} :: title"/>
|
||||
<definition name="head/user/*"
|
||||
template="user/{1} :: /html/head/link"/>
|
||||
|
||||
<definition name="*"
|
||||
template="layout">
|
||||
<put-attribute name="content"
|
||||
value="content/{1}"/>
|
||||
<put-attribute name="title"
|
||||
value="title/{1}"/>
|
||||
<put-attribute name="head"
|
||||
value="head/{1}"/>
|
||||
</definition>
|
||||
|
||||
<definition name="content/*"
|
||||
template="{1} :: content"/>
|
||||
<definition name="title/*"
|
||||
template="{1} :: title"/>
|
||||
<definition name="head/*"
|
||||
template="{1} :: /html/head/link"/>
|
||||
</tiles-definitions>
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring3-3.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:include="title">SecureMail:</title>
|
||||
<link rel="icon" type="image/x-icon" th:href="@{/resources/img/favicon.ico}" href="../resources/img/favicon.ico"/>
|
||||
<link th:href="@{/resources/css/bootstrap.css}" href="../resources/css/bootstrap.css" rel="stylesheet"></link>
|
||||
<style type="text/css">
|
||||
/* Sticky footer styles
|
||||
-------------------------------------------------- */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
/* The html and body elements cannot have any padding or margin. */
|
||||
}
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
/* Negative indent footer by it's height */
|
||||
margin: 0 auto -60px;
|
||||
}
|
||||
|
||||
/* Set the fixed height of the footer here */
|
||||
#push,
|
||||
#footer {
|
||||
height: 60px;
|
||||
}
|
||||
#footer {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */
|
||||
@media (max-width: 767px) {
|
||||
#footer {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Custom page CSS
|
||||
-------------------------------------------------- */
|
||||
/* Not required for template or sticky footer method. */
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 680px;
|
||||
}
|
||||
.container .credit {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
.navbar-form {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<link th:href="@{resources/css/bootstrap-responsive.css}" href="/resources/css/bootstrap-responsive.css" rel="stylesheet"></link>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<script tiles:replace="head"></script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" th:href="@{/}"><img th:src="@{/resources/img/logo.png}" alt="Spring Security Sample"/></a>
|
||||
<div class="nav-collapse collapse">
|
||||
<div th:if="${#httpServletRequest.remoteUser != null}">
|
||||
<form class="navbar-form pull-right" th:action="@{/logout}" method="post">
|
||||
<input type="submit" value="Log out" />
|
||||
</form>
|
||||
<p class="navbar-text pull-right" th:text="${#httpServletRequest.remoteUser}">
|
||||
sample_user
|
||||
</p>
|
||||
</div>
|
||||
<ul class="nav">
|
||||
<li><a th:href="@{/}">Inbox</a></li>
|
||||
<li><a th:href="@{/(form)}">Compose</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Begin page content -->
|
||||
<div class="container">
|
||||
<div class="alert alert-success"
|
||||
th:if="${globalMessage}"
|
||||
th:text="${globalMessage}">
|
||||
Some Success message
|
||||
</div>
|
||||
<div tiles:substituteby="content">
|
||||
Fake content
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="push"><!-- --></div>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p class="muted credit">Visit the <a href="http://spring.io/spring-security">Spring Security</a> site for more <a href="https://github.com/spring-projects/spring-security/blob/master/samples/">samples</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Create</title>
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<div class="container">
|
||||
<h1>Messages : Create</h1>
|
||||
<form id="messageForm"
|
||||
th:action="@{/}"
|
||||
th:object="${message}"
|
||||
action="view.html"
|
||||
method="post">
|
||||
<div th:if="${#fields.hasErrors('*')}"
|
||||
class="alert alert-error">
|
||||
<p th:each="error : ${#fields.errors('*')}"
|
||||
th:text="${error}">
|
||||
Validation error
|
||||
</p>
|
||||
</div>
|
||||
<label for="summary">
|
||||
Summary
|
||||
</label>
|
||||
<input type="text"
|
||||
th:field="*{summary}"
|
||||
th:class="${#fields.hasErrors('summary')} ? 'field-error'"/>
|
||||
<label for="text">
|
||||
Message
|
||||
</label>
|
||||
<textarea th:field="*{text}"
|
||||
th:class="${#fields.hasErrors('text')} ? 'field-error'">
|
||||
</textarea>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : View All</title>
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<h1>Inbox</h1>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Created</th>
|
||||
<th>Summary</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:if="${messages.empty}">
|
||||
<td colspan="2">No messages</td>
|
||||
</tr>
|
||||
<tr th:each="message : ${messages}">
|
||||
<td th:text="${#calendars.format(message.created)}">July 11, 2012 2:17:16 PM CDT</td>
|
||||
<td><a href="view.html" th:href="@{'/' + ${message.id}}" th:text="${message.summary}">The summary</a></td>
|
||||
<td><form class="form-inline" th:action="@{'/' + ${message.id}}" th:method="delete"><input type="submit" value="Delete"/></form></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title tiles:fragment="title">Messages : Create</title>
|
||||
</head>
|
||||
<body>
|
||||
<div tiles:fragment="content">
|
||||
<div class="container">
|
||||
<h1>Message : <span th:text="${message.summary}">A short summary...</span></h1>
|
||||
<dl>
|
||||
<dt>ID</dt>
|
||||
<dd id="id" th:text="${message.id}">123</dd>
|
||||
<dt>Date</dt>
|
||||
<dd id="created" th:text="${#calendars.format(message.created)}">July 11, 2012 2:17:16 PM CDT</dd>
|
||||
<dt>Message</dt>
|
||||
<dd id="text" th:text="${message.text}">A detailed message that is longer than the summary.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -13,11 +13,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/user/**").hasRole("ADMIN")
|
||||
.antMatchers("/resources/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.openidLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll()
|
||||
.authenticationUserDetailsService(new CustomUserDetailsService())
|
||||
.attributeExchange("https://www.google.com/.*")
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |