Rob Winch 485676be8c SEC-2251: Polish Hello World guides
* Correct how to add username and logout to mvc
* Externalize :revnumber:
2013-08-15 12:50:40 -05:00

136 lines
5.4 KiB
Plaintext

= Hello Spring MVC Security Java Config
:author: Rob Winch
:starter-appname: insecuremvc
:completed-appname: hellomvc-jc
:verify-starter-app-include: hello-includes/verify-insecuremvc-app.asc
This guide provides instructions on how to add Spring Security to an existing Spring MVC application without the use of XML.
include::hello-includes/setting-up-the-sample.asc[]
include::hello-includes/secure-the-application.asc[]
=== Registering Spring Security with the war
We have created the Spring Security configuration, but we still need to register it with the war. This can be done using the following steps:
* Right click the _spring-security-samples-{starter-appname}_ project the Package Explorer view
* Select *New->Class*
* Enter _org.springframework.security.samples.config_ for the *Package*
* Enter _SecurityWebApplicationInitializer_ for the *Name*
* Click *Finish*
* Replace the file with the following contents:
.src/main/java/org/springframework/security/samples/config/SecurityWebApplicationInitializer.java
[source,java]
----
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>>
=== Verify SecurityConfig is loaded
Just because <<security-config-java,`SecurityConfig`>> exists, does not mean that our Spring application knows about it. In this instance, our Spring root application context is initialized using MessageWebApplicationInitializer which is included with our spring-security-samples-messages-jc project. You can find a snippet of it below:
[[message-web-application-inititializer-java]]
.MessageWebApplicationInitializer.java
[source,java]
----
@Order(1)
public class MessageWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfiguration.class };
}
// ... other overrides ...
}
----
You will notice it is loading the `RootConfiguration` class which is also included in our spring-security-samples-messages-jc project.
[[root-configuration-java]]
.RootConfiguration.java
[source,java]
----
@Configuration
@ComponentScan(value = "org.springframework.security.samples.config",
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = RootConfiguration.class))
public class RootConfiguration {
}
----
The `@ComponentScan` is loading all configuration in the org.springframework.security.samples.config package. Since <<security-config-java,`SecurityConfig`>> is in this package, it will be loaded with our existing setup and there is nothing more to do.
NOTE: Had <<security-config-java,`SecurityConfig`>> not been loaded, we could have used an `@Import(SecurityConfig)` above the class definition of <<root-configuration-java,`RootConfiguration`>> or added <<security-config-java,`SecurityConfig`>> as one of the results for `getRootConfigClasses()`.
include::hello-includes/exploring-the-secured-application.asc[]
==== Displaying the user name
Now that we have authenticated, let's update the application to display the username. Update main.jsp to contain the following snippet:
.src/main/webapp/WEB-INF/decorators/main.jsp
[source,html]
[subs="verbatim,quotes"]
----
<div class="nav-collapse collapse">
*<p class="navbar-text pull-right">
<c:out value="${pageContext.request.remoteUser}"/>
</p>*
<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.
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>>
==== 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:
.src/main/webapp/index.jsp
[source,html]
[subs="verbatim,quotes"]
----
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
<c:out value="${pageContext.request.remoteUser}"/>
*<c:url var="logoutUrl" value="/logout"/>
<a href="${logoutUrl}">Log out</a>*
</p>
<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>
----
Refresh the page at http://localhost:8080/sample/ and you will see the log out link. Click the link and see that the application logs you out successfully.
include::hello-includes/basic-authentication.asc[]
== Conclusion
You should now now how to secure your application using Spring Security without using any XML.