= 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 if the user is authenticated. 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">
  *<c:if test="${pageContext.request.remoteUser != null}">
    <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>
----

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">
  *<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>
  </c:if>*
  <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>
----
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

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.

include::hello-includes/basic-authentication.asc[]

== Conclusion

You should now now how to secure your application using Spring Security without using any XML. Next, we will see how to link:form.html[customize our login form].
