Skip to content

Commit 043ca5e

Browse files
authored
Merge pull request #352 from mauromol/add-factories-to-auth
Add factories as an extension mechanism for Auth
2 parents 265c526 + 2917a41 commit 043ca5e

File tree

11 files changed

+882
-137
lines changed

11 files changed

+882
-137
lines changed

README.md

+55-27
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ The toolkit is hosted on github. You can download it from:
9393
The toolkit is hosted at [Sonatype OSSRH (OSS Repository Hosting)](http://central.sonatype.org/pages/ossrh-guide.html) that is synced to the Central Repository.
9494

9595
Install it as a maven dependency:
96-
```
96+
```xml
9797
<dependency>
9898
<groupId>com.onelogin</groupId>
9999
<artifactId>java-saml</artifactId>
@@ -444,7 +444,7 @@ If you want to use anything different than javax.servlet.http, you will need to
444444

445445
#### Initiate SSO
446446
In order to send an AuthNRequest to the IdP:
447-
```
447+
```java
448448
Auth auth = new Auth(request, response);
449449
auth.login();
450450
```
@@ -453,16 +453,18 @@ The AuthNRequest will be sent signed or unsigned based on the security settings
453453
The IdP will then return the SAML Response to the user's client. The client is then forwarded to the Attribute Consumer Service of the SP with this information.
454454

455455
We can set a 'RelayState' parameter containing a return url to the login function:
456-
```
456+
```java
457457
String returnUrl = 'https://example.com';
458458
auth.login(relayState=returnUrl)
459459
```
460-
The login method can receive 6 more optional parameters:
461-
- *forceAuthn* When true the AuthNRequest will have the 'ForceAuthn' attribute set to 'true'
462-
- *isPassive* When true the AuthNRequest will have the 'Ispassive' attribute set to 'true'
463-
- *setNameIdPolicy* When true the AuthNRequest will set a nameIdPolicy element.
460+
The login method can receive 3 more optional parameters:
461+
- *authnRequestParams* which in turn allows to shape the AuthNRequest with the following properties:
462+
- *forceAuthn* When true the AuthNRequest will have the `ForceAuthn` attribute set to `true`
463+
- *isPassive* When true the AuthNRequest will have the `IsPassive` attribute set to `true`
464+
- *setNameIdPolicy* When true the AuthNRequest will set a `NameIdPolicy` element
465+
- *allowCreate* When true, and *setNameIdPolicy* is also true, the AuthNRequest will have the `AllowCreate` attribute set to `true` on the `NameIdPolicy` element
466+
- *nameIdValueReq* Indicates to the IdP the subject that should be authenticated
464467
- *stay* Set to true to stay (returns the url string), otherwise set to false to execute a redirection to that url (IdP SSO URL)
465-
- *nameIdValueReq* Indicates to the IdP the subject that should be authenticated
466468
- *parameters* Use it to send extra parameters in addition to the AuthNRequest
467469

468470
By default, the login method initiates a redirect to the SAML Identity Provider. You can use the *stay* parameter, to prevent that, and execute the redirection manually. We need to use that if a match on the future SAMLResponse ID and the AuthNRequest ID to be sent is required. That AuthNRequest ID must be extracted and stored for future validation, so we can't execute the redirection on the login. Instead, set *stay* to true, then get that ID by
@@ -477,7 +479,7 @@ Related to the SP there are 3 important endpoints: The metadata view, the ACS vi
477479

478480
##### SP Metadata
479481
This code will provide the XML metadata file of our SP, based on the info that we provided in the settings files.
480-
```
482+
```java
481483
Auth auth = new Auth();
482484
Saml2Settings settings = auth.getSettings();
483485
String metadata = settings.getSPMetadata();
@@ -497,7 +499,7 @@ Before the XML metadata is exposed, a check takes place to ensure that the info
497499

498500
##### Attribute Consumer Service(ACS)
499501
This code handles the SAML response that the IdP forwards to the SP through the user's client.
500-
```
502+
```java
501503
Auth auth = new Auth(request, response);
502504
auth.processResponse();
503505
if (!auth.isAuthenticated()) {
@@ -575,7 +577,7 @@ Before trying to get an attribute, check that the user is authenticated. If the
575577

576578
##### Single Logout Service (SLS)
577579
This code handles the Logout Request and the Logout Responses.
578-
```
580+
```java
579581
Auth auth = new Auth(request, response);
580582
auth.processSLO();
581583
List<String> errors = auth.getErrors();
@@ -595,7 +597,7 @@ If we don't want that processSLO to destroy the session, pass the keepLocalSessi
595597

596598
#### Initiate SLO
597599
In order to send a Logout Request to the IdP:
598-
```
600+
```java
599601
Auth auth = new Auth(request, response);
600602

601603
String nameId = null;
@@ -618,36 +620,62 @@ String sessionIndex = null;
618620
if (session.getAttribute("sessionIndex") != null) {
619621
sessionIndex = session.getAttribute("sessionIndex").toString();
620622
}
621-
auth.logout(null, nameId, sessionIndex, nameIdFormat);
622-
```
623+
auth.logout(null, new LogoutRequestParams(sessionIndex, nameId, nameIdFormat));
624+
```java
623625
The Logout Request will be sent signed or unsigned based on the security settings 'onelogin.saml2.security.logoutrequest_signed'
624626

625627
The IdP will return the Logout Response through the user's client to the Single Logout Service of the SP.
626628
627629
We can set a 'RelayState' parameter containing a return url to the login function:
628-
```
630+
```java
629631
String returnUrl = 'https://example.com';
630632
auth.logout(relayState=returnUrl)
631633
```
632634

633-
Also there are 7 optional parameters that can be set:
634-
- nameId. That will be used to build the LogoutRequest. If not name_id parameter is set and the auth object processed a SAML Response with a NameId, then this NameId will be used.
635-
- sessionIndex. Identifies the session of the user.
636-
If a match on the LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must to be extracted and stored for future validation, we can get that ID by
637-
- stay. True if we want to stay (returns the url string) False to execute a redirection to that url (IdP SLS URL)
638-
- nameidFormat. The NameID Format that will be set in the LogoutRequest
639-
- nameIdNameQualifier. The NameID NameQualifier that will be set in the LogoutRequest
640-
- nameIdSPNameQualifier. The NameID SP Name Qualifier that will be set in the LogoutRequest
641-
- parameters. Use it to send extra parameters in addition to the LogoutRequest
642-
643-
By default the logout method initiates a redirect to the SAML Identity Provider. You can use the stay parameter, to prevent that, and execute the redirection manually. We need to use that
635+
Also there are other 3 optional parameters that can be set:
636+
- *logoutRequestParams* which in turn allows to shape the LogoutRequest with the following properties:
637+
- *sessionIndex* Identifies the session of the user
638+
- *nameId* That will be used to build the LogoutRequest. If no *nameId* parameter is set and the auth object processed a SAML Response with a `NameID`, then this `NameID` will be used
639+
- *nameidFormat* The `NameID` `Format` that will be set on the LogoutRequest
640+
- *nameIdNameQualifier* The `NameID` `NameQualifier` that will be set on the LogoutRequest
641+
- *nameIdSPNameQualifier* The `NameID` `SPNameQualifier` that will be set on the LogoutRequest
642+
- *stay* True if we want to stay (returns the url string) False to execute a redirection to that url (IdP SLS URL)
643+
- *parameters* Use it to send extra parameters in addition to the LogoutRequest
644+
645+
By default the logout method initiates a redirect to the SAML Identity Provider. You can use the *stay* parameter, to prevent that, and execute the redirection manually. We need to use that
644646
if a match on the future LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must be extracted and stored for future validation so we can't execute the redirection on the logout, instead set stay to true, then get that ID by
645647

646-
```
648+
```java
647649
auth.getLastRequestId()
648650
```
649651
and later executing the redirection manually.
650652

653+
### Extending the provided implementation
654+
655+
All the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRequest`, `LogoutResponse`) can be extended to add or change the processing behavior.
656+
657+
In particular, the classes used to produce outgoing messages (`AuthnRequest`, `LogoutRequest`, and `LogoutResponse`) also provide a `postProcessXml` method that can be overridden to customise the generation of the corresponding SAML message XML, along with the ability to pass in proper extensions of the input parameter classes (`AuthnRequestParams`, `LogoutRequestParams`, and `LogoutResponseParams` respectively).
658+
659+
Once you have prepared your extension classes, in order to make the `Auth` class use them, an appropriate `SamlMessageFactory` implementation can be specified. As an example, assuming you've created two extension classes `AuthnRequestEx` and `SamlResponseEx` to customise the creation of AuthnRequest SAML messages and the validation of SAML responses respectively, as well as an extended `AuthnRequestParamsEx` input parameter class to drive the AuthnRequest generation post-processing, you can do the following:
660+
661+
```java
662+
Auth auth = new Auth(request, response);
663+
auth.setSamlMessageFactory(new SamlMessageFactory() {
664+
@Override
665+
public AuthnRequest createAuthnRequest(Saml2Settings settings, AuthnRequestParams params) {
666+
return new AuthnRequestEx(settings, (AuthnRequestParamsEx) params);
667+
}
668+
669+
@Override
670+
public SamlResponse createSamlResponse(Saml2Settings settings, HttpRequest request) throws Exception {
671+
return new SamlResponseEx(settings, request);
672+
}
673+
});
674+
// then proceed with login...
675+
auth.login(relayState, new AuthnRequestParamsEx()); // the custom generation of AuthnReqeustEx will be executed
676+
// ... or process the response as usual
677+
auth.processResponse(); // the custom validation of SamlResponseEx will be executed
678+
```
651679

652680
### Working behind load balancer
653681

core/src/main/java/com/onelogin/saml2/authn/AuthnRequestParams.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public boolean isAllowCreate() {
160160
/**
161161
* @return the subject that should be authenticated
162162
*/
163-
protected String getNameIdValueReq() {
163+
public String getNameIdValueReq() {
164164
return nameIdValueReq;
165165
}
166166
}

core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public LogoutRequest(Saml2Settings settings, HttpRequest request) {
242242
* @param settings
243243
* OneLogin_Saml2_Settings
244244
* @param params
245-
* a set of authentication request input parameters that shape the
245+
* a set of logout request input parameters that shape the
246246
* request to create
247247
*/
248248
public LogoutRequest(Saml2Settings settings, LogoutRequestParams params) {

core/src/main/java/com/onelogin/saml2/logout/LogoutRequestParams.java

+11-20
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,31 @@ public class LogoutRequestParams {
99
* SessionIndex. When the user is logged, this stored it from the AuthnStatement
1010
* of the SAML Response
1111
*/
12-
private String sessionIndex;
12+
private final String sessionIndex;
1313

1414
/**
1515
* NameID.
1616
*/
17-
private String nameId;
17+
private final String nameId;
1818

1919
/**
2020
* NameID Format.
2121
*/
22-
private String nameIdFormat;
22+
private final String nameIdFormat;
2323

2424
/**
2525
* nameId NameQualifier
2626
*/
27-
private String nameIdNameQualifier;
27+
private final String nameIdNameQualifier;
2828

2929
/**
3030
* nameId SP NameQualifier
3131
*/
32-
private String nameIdSPNameQualifier;
32+
private final String nameIdSPNameQualifier;
3333

3434
/** Create an empty set of logout request input parameters. */
3535
public LogoutRequestParams() {
36+
this(null, null);
3637
}
3738

3839
/**
@@ -118,45 +119,35 @@ protected LogoutRequestParams(LogoutRequestParams source) {
118119
/**
119120
* @return the name ID
120121
*/
121-
protected String getNameId() {
122+
public String getNameId() {
122123
return nameId;
123124
}
124125

125-
/**
126-
* Sets the name ID
127-
*
128-
* @param nameId
129-
* the name ID to set
130-
*/
131-
protected void setNameId(String nameId) {
132-
this.nameId = nameId;
133-
}
134-
135126
/**
136127
* @return the name ID format
137128
*/
138-
protected String getNameIdFormat() {
129+
public String getNameIdFormat() {
139130
return nameIdFormat;
140131
}
141132

142133
/**
143134
* @return the name ID name qualifier
144135
*/
145-
protected String getNameIdNameQualifier() {
136+
public String getNameIdNameQualifier() {
146137
return nameIdNameQualifier;
147138
}
148139

149140
/**
150141
* @return the name ID SP name qualifier
151142
*/
152-
protected String getNameIdSPNameQualifier() {
143+
public String getNameIdSPNameQualifier() {
153144
return nameIdSPNameQualifier;
154145
}
155146

156147
/**
157148
* @return the session index
158149
*/
159-
protected String getSessionIndex() {
150+
public String getSessionIndex() {
160151
return sessionIndex;
161152
}
162153
}

0 commit comments

Comments
 (0)