Skip to content

Commit 7788469

Browse files
author
Dave Syer
committed
Add docs for 'click' app
1 parent 02450dd commit 7788469

File tree

1 file changed

+142
-1
lines changed

1 file changed

+142
-1
lines changed

click/README.adoc

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,145 @@ just built, by adding an explicit link to login with Facebook. Instead
66
of being redirected immediately, the new link will be visible on the
77
home page, and the user can choose to login or to stay
88
unauthenticated. Only when the user has clicked on the link will he be
9-
shown the secure content.
9+
shown the secure content.
10+
11+
== Conditional Content in Home Page
12+
13+
To render some content conditional on whether the user is
14+
authenticated or not we could use server side rendering (e.g. with
15+
Freemarker or Tymeleaf), or we can just ask the browser to to it,
16+
using some JavaScript. To do that we are going to use
17+
https://angularjs.org/[AngularJS], but if you prefer to use a
18+
different framework, it shouldn't be very hard to translate the client
19+
code.
20+
21+
To get started with AngularJS we need to mark the HTML `<body>` as a
22+
Angular app container:
23+
24+
.index.html
25+
[source,html]
26+
----
27+
<body ng-app="app" ng-controller="home as home">
28+
...
29+
</body>
30+
----
31+
32+
and the `<div>` elements in the body can be bound to a model that
33+
controls which parts of it are displayed:
34+
35+
.index.html
36+
[source,html]
37+
----
38+
<div class="container" ng-show="!home.authenticated">
39+
Login with: <a href="/login">Facebook</a>
40+
</div>
41+
<div class="container" ng-show="home.authenticated">
42+
Logged in as: <span ng-bind="home.user"></span>
43+
</div>
44+
----
45+
46+
This HTML sets us up with a need for a "home" controller that has an
47+
`authenticated` flag, and a `user` object describing the authenticated
48+
user. Here's a simple implementation of those features (drop them in
49+
at the end of the `<body>`):
50+
51+
.index.html
52+
[source,html]
53+
----
54+
<script type="text/javascript" src="/webjars/angularjs/angular.min.js"></script>
55+
<script type="text/javascript">
56+
angular.module("app", []).controller("home", function($http) {
57+
var self = this;
58+
$http.get("/user").success(function(data) {
59+
self.user = data.userAuthentication.details.name;
60+
self.authenticated = true;
61+
}).error(function() {
62+
self.user = "N/A";
63+
self.authenticated = false;
64+
});
65+
});
66+
</script>
67+
----
68+
69+
== Server Side Changes
70+
71+
For this to work we need some changes on the server side. The "home"
72+
controller needs an endpoint at "/user" that describes the currently
73+
authenticated user. That's quite easy to do, e.g. in our main class:
74+
75+
.SocialApplication
76+
[source,java]
77+
----
78+
@SpringBootApplication
79+
@EnableOAuth2Sso
80+
@RestController
81+
public class SocialApplication {
82+
83+
@RequestMapping("/user")
84+
public Principal user(Principal principal) {
85+
return principal;
86+
}
87+
88+
public static void main(String[] args) {
89+
SpringApplication.run(SocialApplication.class, args);
90+
}
91+
92+
}
93+
----
94+
95+
Note the use of `@RestController` and `@RequestMapping` and the
96+
`java.util.Principal` we inject into the handler method.
97+
98+
WARNING: It's not a great idea to return a whole `Principal` in a
99+
`/user` endpoint like that (it might contain information you would
100+
rather not reveal to a browser client). We only did it to get
101+
something working quickly. Later in the guide we will convert the
102+
endpoint to hide the information we don't need the browser to have.
103+
104+
This app will now work fine and authenticate as before, but without
105+
giving the user a chance to click on the link we just provided. To
106+
make the link visible we also need to switch off the security on the
107+
home page by adding a `WebSecurityConfigurer`:
108+
109+
.SocialApplication
110+
[source,java]
111+
----
112+
@SpringBootApplication
113+
@EnableOAuth2Sso
114+
@RestController
115+
public class SocialApplication extends WebSecurityConfigurerAdapter {
116+
117+
...
118+
119+
@Override
120+
protected void configure(HttpSecurity http) throws Exception {
121+
http
122+
.antMatcher("/**")
123+
.authorizeRequests()
124+
.antMatchers("/", "/login**", "/webjars/**")
125+
.permitAll()
126+
.anyRequest()
127+
.authenticated();
128+
}
129+
130+
}
131+
----
132+
133+
Spring Boot attaches a special meaning to a `WebSecurityConfigurer` on
134+
the class that carries the `@EnableOAuth2Sso` annotation: it uses it
135+
to configure the security filter chain that carries the OAuth2
136+
authentication processor. So all we need to do to make out home page
137+
visible is to explicitly `authorizeRequests()` to the home page and
138+
the static resources it contains (we also include access to the login
139+
endpoints which handle the authentication). All other requests
140+
(e.g. to the `/user` endpoint) require authentication.
141+
142+
With that change in place the application is complete, and if you run
143+
it and visit the home page you should see a nicely styled HTML link to
144+
"login with Facebook". The link takes you not directly to Facebook,
145+
but to the local path that processes the authentication (and sends a
146+
redirect to Facebook). Once you have authenticated you get redirected
147+
back to the local app, where it now displays your name (assuming you
148+
have set up your permissions in Facebook to allow access to that
149+
data).
150+

0 commit comments

Comments
 (0)