Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build/
nbbuild/
dist/
nbdist/
.nb-gradle/# See http://help.github.com/ignore-files/ for more about ignoring files.
.nb-gradle/# See https://help.github.com/ignore-files/ for more about ignoring files.
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.writing.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Except where otherwise noted, this work is licensed under http://creativecommons.org/licenses/by-nd/3.0/
Except where otherwise noted, this work is licensed under https://creativecommons.org/licenses/by-nd/3.0/
2 changes: 1 addition & 1 deletion basic/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Editor configuration, see http://editorconfig.org
# Editor configuration, see https://editorconfig.org
root = true

[*]
Expand Down
12 changes: 6 additions & 6 deletions basic/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ In this tutorial we show some nice features of Spring Security, Spring Boot and

HTML5, rich browser-based features, and the "single page application" are extremely valuable tools for modern developers, but any meaningful interactions will involve a backend server, so as well as static content (HTML, CSS and JavaScript) we are going to need a backend server. The backend server can play any or all of a number of roles: serving static content, sometimes (but not so often these days) rendering dynamic HTML, authenticating users, securing access to protected resources, and (last but not least) interacting with JavaScript in the browser through HTTP and JSON (sometimes referred to as a REST API).

Spring has always been a popular technology for building the backend features (especially in the enterprise), and with the advent of http://projects.spring.io/spring-boot[Spring Boot] things have never been easier. Let's have a look at how to build a new single page application from nothing using Spring Boot, Angular and Twitter Bootstrap. There's no particular reason to choose that specific stack, but it is quite popular, especially with the core Spring constituency in enterprise Java shops, so it's a worthwhile starting point.
Spring has always been a popular technology for building the backend features (especially in the enterprise), and with the advent of https://projects.spring.io/spring-boot[Spring Boot] things have never been easier. Let's have a look at how to build a new single page application from nothing using Spring Boot, Angular and Twitter Bootstrap. There's no particular reason to choose that specific stack, but it is quite popular, especially with the core Spring constituency in enterprise Java shops, so it's a worthwhile starting point.

== Create a New Project

Expand Down Expand Up @@ -37,7 +37,7 @@ You can then import that project (it's a normal Maven Java project by default) i
[[using-spring-boot-cli]]
=== Using Spring Boot CLI

You can create the same project using the http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#getting-started-installing-the-cli[Spring Boot CLI], like this:
You can create the same project using the https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#getting-started-installing-the-cli[Spring Boot CLI], like this:

[source]
----
Expand All @@ -54,7 +54,7 @@ If you prefer you can also get the same code directly as a .zip file from the ht
[[using-spring-tool-suite]]
=== Using Spring Tool Suite

In http://spring.io/tools/sts[Spring Tool Suite] (a set of Eclipse plugins) you can also create and import a project using a wizard at `File->New->Spring Starter Project`. Then jump to the link:#add-a-home-page[next section]. IntelliJ IDEA and NetBeans have similar features.
In https://spring.io/tools/sts[Spring Tool Suite] (a set of Eclipse plugins) you can also create and import a project using a wizard at `File->New->Spring Starter Project`. Then jump to the link:#add-a-home-page[next section]. IntelliJ IDEA and NetBeans have similar features.

[[add-a-home-page]]
== Add an Angular App
Expand Down Expand Up @@ -231,7 +231,7 @@ The interactions between the browser and the backend can be seen in your browser
|GET |/resource |200 |JSON greeting
|===

You might not see the 401 because the browser treats the home page load as a single interaction, and you might see 2 requests for "/resource" because there is a http://en.wikipedia.org/wiki/Cross-origin_resource_sharing[CORS] negotiation.
You might not see the 401 because the browser treats the home page load as a single interaction, and you might see 2 requests for "/resource" because there is a https://en.wikipedia.org/wiki/Cross-origin_resource_sharing[CORS] negotiation.

Look more closely at the requests and you will see that all of them have an "Authorization" header, something like this:

Expand All @@ -250,12 +250,12 @@ On the face of it, it seems like we did a pretty good job, it's concise, easy to

* The authentication UI is ubiquitous but ugly (browser dialog).

* There is no protection from http://en.wikipedia.org/wiki/Cross-site_request_forgery[Cross Site Request Forgery] (CSRF).
* There is no protection from https://en.wikipedia.org/wiki/Cross-site_request_forgery[Cross Site Request Forgery] (CSRF).

CSRF isn't really an issue with our application as it stands since it only needs to GET the backend resources (i.e. no state is changed in the server). As soon as you have a POST, PUT or DELETE in your application it simply isn't secure any more by any reasonable modern measure.

In the <<_the_login_page_angular_js_and_spring_security_part_ii,next section in this series>> we will extend the application to use form-based authentication, which is a lot more flexible than HTTP Basic. Once we have a form we will need CSRF protection, and both Spring Security and Angular have some nice out-of-the box features to help with this. Spoiler: we are going to need to use the `HttpSession`.

****
Thanks: I would like to thank everyone who helped me develop this series, and in particular http://spring.io/team/rwinch[Rob Winch] and https://twitter.com/thspaeth[Thorsten Spaeth] for their careful reviews of the text and source code, and for teaching me a few tricks I didn't know even about the parts I thought I was most familiar with.
Thanks: I would like to thank everyone who helped me develop this series, and in particular https://spring.io/team/rwinch[Rob Winch] and https://twitter.com/thspaeth[Thorsten Spaeth] for their careful reviews of the text and source code, and for teaching me a few tricks I didn't know even about the parts I thought I was most familiar with.
****
2 changes: 1 addition & 1 deletion basic/src/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import 'core-js/es7/reflect';

/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
* Needed for: All but Chrome, Firefox and Opera. https://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.

Expand Down
12 changes: 6 additions & 6 deletions double/README.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[[_multiple_ui_applications_and_a_gateway_single_page_application_with_spring_and_angular_js_part_vi]]
= Multiple UI Applications and a Gateway

In this section we continue <<_sso_with_oauth2_angular_js_and_spring_security_part_v,our discussion>> of how to use http://projects.spring.io/spring-security[Spring Security] with http://angular.io[Angular] in a "single page application". Here we show how to use http://projects.spring.io/spring-security-oauth/[Spring Session] together with http://projects.spring.io/spring-cloud/[Spring Cloud] to combine the features of the systems we built in parts II and IV, and actually end up building 3 single page applications with quite different responsibilities. The aim is to build a Gateway (like in <<_the_api_gateway_pattern_angular_js_and_spring_security_part_iv,part IV>>) that is used not only for API resources but also to load the UI from a backend server. We simplify the token-wrangling bits of <<_the_login_page_angular_js_and_spring_security_part_ii,part II>> by using the Gateway to pass through the authentication to the backends. Then we extend the system to show how we can make local, granular access decisions in the backends, while still controlling identity and authentication at the Gateway. This is a very powerful model for building distributed systems in general, and has a number of benefits that we can explore as we introduce the features in the code we build.
In this section we continue <<_sso_with_oauth2_angular_js_and_spring_security_part_v,our discussion>> of how to use https://projects.spring.io/spring-security[Spring Security] with https://angular.io[Angular] in a "single page application". Here we show how to use https://projects.spring.io/spring-security-oauth/[Spring Session] together with https://projects.spring.io/spring-cloud/[Spring Cloud] to combine the features of the systems we built in parts II and IV, and actually end up building 3 single page applications with quite different responsibilities. The aim is to build a Gateway (like in <<_the_api_gateway_pattern_angular_js_and_spring_security_part_iv,part IV>>) that is used not only for API resources but also to load the UI from a backend server. We simplify the token-wrangling bits of <<_the_login_page_angular_js_and_spring_security_part_ii,part II>> by using the Gateway to pass through the authentication to the backends. Then we extend the system to show how we can make local, granular access decisions in the backends, while still controlling identity and authentication at the Gateway. This is a very powerful model for building distributed systems in general, and has a number of benefits that we can explore as we introduce the features in the code we build.

____
Reminder: if you are working through this section with the sample application, be sure to clear your browser cache of cookies and HTTP Basic credentials. In Chrome the best way to do that is to open a new incognito window.
Expand All @@ -17,7 +17,7 @@ Like the other sample applications in this series it has a UI (HTML and JavaScri

The browser goes to the Gateway for everything and it doesn't have to know about the architecture of the backend (fundamentally, it has no idea that there is a back end). One of the things the browser does in this Gateway is authentication, e.g. it sends a username and password like in <<_the_login_page_angular_js_and_spring_security_part_ii,Section II>>, and it gets a cookie in return. On subsequent requests it presents the cookie automatically and the Gateway passes it through to the backends. No code needs to be written on the client to enable the cookie passing. The backends use the cookie to authenticate and because all components share a session they share the same information about the user. Contrast this with <<_sso_with_oauth2_angular_js_and_spring_security_part_v,Section V>> where the cookie had to be converted to an access token in the Gateway, and the access token then had to be independently decoded by all the backend components.

As in <<_the_api_gateway_pattern_angular_js_and_spring_security_part_iv,Section IV>> the Gateway simplifies the interaction between clients and servers, and it presents a small, well-defined surface on which to deal with security. For example, we don't need to worry about http://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross Origin Resource Sharing], which is a welcome relief since it is easy to get wrong.
As in <<_the_api_gateway_pattern_angular_js_and_spring_security_part_iv,Section IV>> the Gateway simplifies the interaction between clients and servers, and it presents a small, well-defined surface on which to deal with security. For example, we don't need to worry about https://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross Origin Resource Sharing], which is a welcome relief since it is easy to get wrong.

The source code for the complete project we are going to build is in https://github.com/spring-guides/tut-spring-security-and-angular-js/tree/master/double[Github here], so you can just clone the project and work directly from there if you want. There is an extra component in the end state of this system ("double-admin") so ignore that for now.

Expand Down Expand Up @@ -83,9 +83,9 @@ possibly work) we can just take an empty Spring Boot web application and add the
As we saw in
<<_spring_and_angular_js_a_secure_single_page_application,Section I>> there are
several ways to do that, and one is to use the
http://start.spring.io[Spring Initializr] to generate a skeleton project.
Even easier, is to use the http://cloud-start.spring.io[Spring Cloud Initializr]
which is the same thing, but for http://cloud.spring.io[Spring Cloud]
https://start.spring.io[Spring Initializr] to generate a skeleton project.
Even easier, is to use the https://cloud-start.spring.io[Spring Cloud Initializr]
which is the same thing, but for https://cloud.spring.io[Spring Cloud]
applications.
Using the same sequence of command line operations as in Section I:

Expand Down Expand Up @@ -461,5 +461,5 @@ A powerful feature is that the backends can independently have any kind of authe
A bonus feature of this architecture (single Gateway controlling authentication, and shared session token across all components) is that "Single Logout", a feature we identified as difficult to implement in <<_sso_with_oauth2_angular_js_and_spring_security_part_v,Section V>>, comes for free. To be more precise, one particular approach to the user experience of single logout is automatically available in our finished system: if a user logs out of any of the UIs (Gateway, UI backend or Admin backend), he is logged out of all the others, assuming that each individual UI implemented a "logout" feature the same way (invalidating the session).

****
Thanks: I would like to thank again everyone who helped me develop this series, and in particular http://spring.io/team/rwinch[Rob Winch] and https://twitter.com/thspaeth[Thorsten Späth] for their careful reviews of the sections and sources code. Since <<_spring_and_angular_js_a_secure_single_page_application,Section I>> was published it hasn't changed much but all the other parts have evolved in response to comments and insights from readers, so thank you also to anyone who read the sections and took the trouble to join in the discussion.
Thanks: I would like to thank again everyone who helped me develop this series, and in particular https://spring.io/team/rwinch[Rob Winch] and https://twitter.com/thspaeth[Thorsten Späth] for their careful reviews of the sections and sources code. Since <<_spring_and_angular_js_a_secure_single_page_application,Section I>> was published it hasn't changed much but all the other parts have evolved in response to comments and insights from readers, so thank you also to anyone who read the sections and took the trouble to join in the discussion.
****
2 changes: 1 addition & 1 deletion double/admin/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Editor configuration, see http://editorconfig.org
# Editor configuration, see https://editorconfig.org
root = true

[*]
Expand Down
2 changes: 1 addition & 1 deletion double/admin/src/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import 'core-js/es7/reflect';

/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
* Needed for: All but Chrome, Firefox and Opera. https://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.

Expand Down
2 changes: 1 addition & 1 deletion double/gateway/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Editor configuration, see http://editorconfig.org
# Editor configuration, see https://editorconfig.org
root = true

[*]
Expand Down
2 changes: 1 addition & 1 deletion double/gateway/src/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import 'core-js/es7/reflect';

/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
* Needed for: All but Chrome, Firefox and Opera. https://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.

Expand Down
2 changes: 1 addition & 1 deletion double/ui/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Editor configuration, see http://editorconfig.org
# Editor configuration, see https://editorconfig.org
root = true

[*]
Expand Down
2 changes: 1 addition & 1 deletion double/ui/src/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import 'core-js/es7/reflect';

/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
* Needed for: All but Chrome, Firefox and Opera. https://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.

Expand Down
Loading