Skip to content

Commit 0759a58

Browse files
committed
Resolve #69
1 parent 5f8a15c commit 0759a58

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

_posts/2015-03-17-security.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ You can secure your application or only some parts using a filter (a RouteHandle
1010
in the order they are added/defined so put your security filter in front of regular routes (regular routes are
1111
endpoint routes for a request).
1212

13+
#### Simple
14+
1315
I will show you a simple implementation for a security filter.
1416

1517
```java
@@ -86,6 +88,97 @@ The authentication tests to see if the 'username' attribute is present in the se
8688
than call the regular route with `routeContext.next()` else redirect to the login page.
8789
I added `originalDestination` attribute because after authentication process I want to continue with the original destination (original url).
8890

91+
#### PAC4J integration
92+
93+
Since version `1.7.0`, Pippo comes with a new module, pippo-pac4j, that add [PAC4J](http://www.pac4j.org) support in Pippo.
94+
In few words, PAC4J is a Java security engine that supports most authentication mechanism (OAuth, SAML, CAS, LDAP, SQL, ...) and
95+
authorization mechanism (Roles/permissions, Anonymous/remember me/(fully) authenticated, CORS, CSRF, ...).
96+
The integration with PAC4J in Pippo is easy and straightforward.
97+
The `pippo-pac4j` module comes with three components (routes/filters):
98+
- `Pac4jSecurityHandler` (before filter) that protects an URL
99+
- `Pac4jLogoutHandler` that handles the (application + identity provider) logout process
100+
- `Pac4jCallbackHandler` that finishes the login process for an indirect client
101+
102+
Below, I present you some snippet code to have a more clear image about this integration:
103+
```java
104+
public class DemoApplication extends Application
105+
{
106+
107+
@Override
108+
protected void onInit()
109+
{
110+
// PAC4J config
111+
Config config = getPac4jConfig();
112+
113+
// authentication filter
114+
ANY(securePaths(), new Pac4jSecurityHandler(config, "FormClient"));
115+
116+
// login
117+
GET("/login", routeContext -> {
118+
String error = routeContext.getParameter("error").toString();
119+
if (error != null)
120+
{
121+
// and error from PAC4J authentication
122+
routeContext.flashError(getMessages().get("login.invalid", routeContext));
123+
routeContext.redirect("login");
124+
}
125+
else
126+
{
127+
// render "login" template (it's a form)
128+
routeContext.render("login");
129+
}
130+
});
131+
Pac4jCallbackHandler callbackHandler = new Pac4jCallbackHandler(config);
132+
callbackHandler.setRenewSession(false);
133+
POST("/login", callbackHandler);
134+
135+
// logout
136+
Pac4jLogoutHandler logoutHandler = new Pac4jLogoutHandler(config, "/");
137+
logoutHandler.setDestroySession(true);
138+
GET("/logout", logoutHandler);
139+
140+
// OTHER BUSSINES ROUTES
141+
}
142+
143+
@SuppressWarnings("unchecked")
144+
private static Optional<CommonProfile> getUserProfile(RouteContext routeContext)
145+
{
146+
PippoWebContext webContext = new PippoWebContext(routeContext);
147+
ProfileManager manager = new ProfileManager(webContext);
148+
149+
return manager.get(true);
150+
}
151+
152+
}
153+
```
154+
155+
First of all you must create a PAC4J's config.
156+
A possible solution is to create a static `getPac4jConfig` method with an implementation like:
157+
```java
158+
private static Config getPac4jConfig() {
159+
// create a client (form based)
160+
FormClient formClient = new FormClient("http://localhost:8888/login", myUsernamePasswordAuthenticator);
161+
162+
// create the config object
163+
Config config = new Config("http://localhost:8888/login", formClient);
164+
165+
// set http action handler
166+
config.setHttpActionAdapter(PippoNopHttpActionAdapter.INSTANCE);
167+
168+
return config;
169+
}
170+
```
171+
172+
Other solution is to define all settings related to PAC4J in your `application.properties` ant to use `SettingsConfigFactory` class:
173+
```java
174+
Config config = new SettingsConfigFactory(getPippoSettings()).build();
175+
```
176+
177+
On `GET /login` route is rendered the login form. The form contains fields like username and password, an a `POST /login` action.
178+
179+
If you want to see a more complex example please see [pippo-demo-pac4j]({{ site.demourl }}/pippo-demo-basic) module.
180+
A possible integration with LDAP/AP is presented [here](https://groups.google.com/forum/#!topic/pac4j-users/uxXn-yPo4Rw).
181+
89182
#### Cross-Site Request Forgery (CSRF) Protection
90183

91184
Pippo includes a simple CSRF handler which will automatically generate a CSRF token on GET requests, if there is no token in the current session, and verify that POST requests include the session's CSRF token.

0 commit comments

Comments
 (0)