66import java .security .PrivateKey ;
77import java .security .SignatureException ;
88import java .util .ArrayList ;
9- import java .util .Calendar ;
109import java .util .Collection ;
1110import java .util .HashMap ;
1211import java .util .List ;
1615import javax .servlet .http .HttpServletRequest ;
1716
1817import org .apache .commons .lang3 .StringUtils ;
18+ import org .joda .time .DateTime ;
1919import org .slf4j .Logger ;
2020import org .slf4j .LoggerFactory ;
2121
@@ -72,7 +72,7 @@ public class Auth {
7272 /**
7373 * SessionNotOnOrAfter. When the user is logged, this stored it from the AuthnStatement of the SAML Response
7474 */
75- private Calendar sessionExpiration ;
75+ private DateTime sessionExpiration ;
7676
7777 /**
7878 * User attributes data.
@@ -104,6 +104,19 @@ public Auth() throws IOException, SettingsException {
104104 this (new SettingsBuilder ().fromFile ("onelogin.saml.properties" ).build (), null , null );
105105 }
106106
107+ /**
108+ * Initializes the SP SAML instance.
109+ *
110+ * @param filename
111+ * String Filename with the settings
112+ *
113+ * @throws IOException
114+ * @throws SettingsException
115+ */
116+ public Auth (String filename ) throws IOException , SettingsException {
117+ this (new SettingsBuilder ().fromFile (filename ).build (), null , null );
118+ }
119+
107120 /**
108121 * Initializes the SP SAML instance.
109122 *
@@ -119,6 +132,23 @@ public Auth(HttpServletRequest request, HttpServletResponse response) throws IOE
119132 this (new SettingsBuilder ().fromFile ("onelogin.saml.properties" ).build (), request , response );
120133 }
121134
135+ /**
136+ * Initializes the SP SAML instance.
137+ *
138+ * @param filename
139+ * String Filename with the settings
140+ * @param request
141+ * HttpServletRequest object to be processed
142+ * @param response
143+ * HttpServletResponse object to be used
144+ *
145+ * @throws SettingsException
146+ * @throws IOException
147+ */
148+ public Auth (String filename , HttpServletRequest request , HttpServletResponse response ) throws SettingsException , IOException {
149+ this (new SettingsBuilder ().fromFile (filename ).build (), request , response );
150+ }
151+
122152 /**
123153 * Initializes the SP SAML instance.
124154 *
@@ -167,13 +197,14 @@ public void setStrict(Boolean value)
167197 * When true the AuthNReuqest will set the ForceAuthn='true'
168198 * @param isPassive
169199 * When true the AuthNReuqest will set the IsPassive='true'
170- *
200+ * @param setNameIdPolicy
201+ * When true the AuthNReuqest will set a nameIdPolicy
171202 * @throws IOException
172203 */
173- public void login (String returnTo , Boolean forceAuthn , Boolean isPassive ) throws IOException {
204+ public void login (String returnTo , Boolean forceAuthn , Boolean isPassive , Boolean setNameIdPolicy ) throws IOException {
174205 Map <String , String > parameters = new HashMap <String , String >();
175206
176- AuthnRequest authnRequest = new AuthnRequest (settings , forceAuthn , isPassive );
207+ AuthnRequest authnRequest = new AuthnRequest (settings , forceAuthn , isPassive , setNameIdPolicy );
177208
178209 String samlRequest = authnRequest .getEncodedAuthnRequest ();
179210 parameters .put ("SAMLRequest" , samlRequest );
@@ -206,7 +237,19 @@ public void login(String returnTo, Boolean forceAuthn, Boolean isPassive) throws
206237 * @throws IOException
207238 */
208239 public void login () throws IOException {
209- login (null ,false , false );
240+ login (null ,false , false , true );
241+ }
242+
243+ /**
244+ * Initiates the SSO process.
245+ *
246+ * @param returnTo
247+ * The target URL the user should be returned to after login.
248+ *
249+ * @throws IOException
250+ */
251+ public void login (String returnTo ) throws IOException {
252+ login (returnTo ,false , false , true );
210253 }
211254
212255 /**
@@ -261,6 +304,20 @@ public void logout() throws IOException, XMLEntityException {
261304 logout (null , null , null );
262305 }
263306
307+ /**
308+ * Initiates the SLO process.
309+ *
310+ * @param returnTo
311+ * The target URL the user should be returned to after logout.
312+ *
313+ * @throws IOException
314+ * @throws XMLEntityException
315+ */
316+ public void logout (String returnTo ) throws IOException , XMLEntityException {
317+ logout (returnTo , null , null );
318+ }
319+
320+
264321 /**
265322 * @return The url of the Single Sign On Service
266323 */
@@ -343,7 +400,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
343400 errorReason = logoutResponse .getError ();
344401 } else {
345402 String status = logoutResponse .getStatus ();
346- if (!status .equals (Constants .STATUS_SUCCESS )) {
403+ if (status == null || !status .equals (Constants .STATUS_SUCCESS )) {
347404 errors .add ("logout_not_success" );
348405 LOGGER .error ("processSLO error. logout_not_success" );
349406 LOGGER .debug (" --> " + samlResponseParameter );
@@ -378,7 +435,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
378435 parameters .put ("SAMLResponse" , samlLogoutResponse );
379436
380437 String relayState = request .getParameter ("RelayState" );
381- if (relayState != null && ! relayState . isEmpty () ) {
438+ if (relayState != null ) {
382439 parameters .put ("RelayState" , relayState );
383440 }
384441
@@ -419,10 +476,10 @@ public final boolean isAuthenticated() {
419476 }
420477
421478 /**
422- * @return the set of the names of the SAML attributes.
479+ * @return the list of the names of the SAML attributes.
423480 */
424- public final Collection <String > getAttributesName () {
425- return attributes .keySet ();
481+ public final List <String > getAttributesName () {
482+ return new ArrayList < String >( attributes .keySet () );
426483 }
427484
428485 /**
@@ -461,13 +518,13 @@ public final String getSessionIndex()
461518 /**
462519 * @return the SessionNotOnOrAfter of the assertion
463520 */
464- public final Calendar getSessionExpiration ()
521+ public final DateTime getSessionExpiration ()
465522 {
466523 return sessionExpiration ;
467524 }
468525
469526 /**
470- * @return an array with the errors, the array is empty when the settings is ok
527+ * @return an array with the errors, the array is empty when the validation was successful
471528 */
472529 public List <String > getErrors ()
473530 {
@@ -511,38 +568,7 @@ public Boolean isDebugActive() {
511568 */
512569 public String buildRequestSignature (String samlRequest , String relayState , String signAlgorithm )
513570 {
514- String signature = "" ;
515-
516- if (!settings .checkSPCerts ()) {
517- String errorMsg = "Trying to sign the SAML Request but can't load the SP certs" ;
518- LOGGER .error ("buildRequestSignature error." + errorMsg );
519- throw new IllegalArgumentException (errorMsg );
520- }
521-
522- PrivateKey key = settings .getSPkey ();
523-
524- String msg = "SAMLRequest=" + Util .urlEncoder (samlRequest );
525- msg += "&RelayState=" + Util .urlEncoder (relayState );
526- msg += "&SigAlg=" + Util .urlEncoder (signAlgorithm );
527-
528- try {
529- signature = Util .base64encoder (Util .sign (msg , key , signAlgorithm ));
530- } catch (InvalidKeyException e ) {
531- LOGGER .error ("buildRequestSignature error." + e .getMessage ());
532- } catch (NoSuchAlgorithmException e ) {
533- LOGGER .error ("buildRequestSignature error." + e .getMessage ());
534- } catch (SignatureException e ) {
535- LOGGER .error ("buildRequestSignature error." + e .getMessage ());
536- }
537-
538- if (signature .isEmpty ()) {
539- String errorMsg = "There was a problem when calculating the Signature of the SAMLRequest" ;
540- LOGGER .error ("buildRequestSignature error. " + errorMsg );
541- throw new IllegalArgumentException (errorMsg );
542- }
543-
544- LOGGER .debug ("buildRequestSignature success. --> " + signature );
545- return signature ;
571+ return buildSignature (samlRequest , relayState , signAlgorithm , "SAMLRequest" );
546572 }
547573
548574 /**
@@ -559,37 +585,45 @@ public String buildRequestSignature(String samlRequest, String relayState, Strin
559585 */
560586 public String buildResponseSignature (String samlResponse , String relayState , String signAlgorithm )
561587 {
562- String signature = "" ;
563-
564- if (!settings .checkSPCerts ()) {
565- String errorMsg = "Trying to sign the SAML Response but can't load the SP certs" ;
566- LOGGER .error ("buildResponseSignature error. " + errorMsg );
567- throw new IllegalArgumentException (errorMsg );
568- }
569-
570- PrivateKey key = settings .getSPkey ();
571-
572- String msg = "SAMLResponse=" + Util .urlEncoder (samlResponse );
573- msg += "&RelayState=" + Util .urlEncoder (relayState );
574- msg += "&SigAlg=" + Util .urlEncoder (signAlgorithm );
575-
576- try {
577- signature = Util .base64encoder (Util .sign (msg , key , signAlgorithm ));
578- } catch (InvalidKeyException e ) {
579- LOGGER .error ("buildResponseSignature error. " + e .getMessage ());
580- } catch (NoSuchAlgorithmException e ) {
581- LOGGER .error ("buildResponseSignature error. " + e .getMessage ());
582- } catch (SignatureException e ) {
583- LOGGER .error ("buildResponseSignature error." + e .getMessage ());
584- }
585-
586- if (signature .isEmpty ()) {
587- String errorMsg = "There was a problem when calculating the Signature of the SAMLResponse" ;
588- LOGGER .error ("buildResponseSignature error. " + errorMsg );
589- throw new IllegalArgumentException (errorMsg );
590- }
591-
592- LOGGER .debug ("buildResponseSignature success. --> " + signature );
593- return signature ;
588+ return buildSignature (samlResponse , relayState , signAlgorithm , "SAMLResponse" );
589+ }
590+
591+ private String buildSignature (String samlMessage , String relayState , String signAlgorithm , String type )
592+ {
593+ String signature = "" ;
594+
595+ if (!settings .checkSPCerts ()) {
596+ String errorMsg = "Trying to sign the " + type + " but can't load the SP certs" ;
597+ LOGGER .error ("buildSignature error. " + errorMsg );
598+ throw new IllegalArgumentException (errorMsg );
599+ }
600+
601+ PrivateKey key = settings .getSPkey ();
602+
603+ String msg = type + "=" + Util .urlEncoder (samlMessage );
604+ if (relayState != null ) {
605+ msg += "&RelayState=" + Util .urlEncoder (relayState );
606+ }
607+
608+ if (signAlgorithm == null || signAlgorithm .isEmpty ()) {
609+ signAlgorithm = Constants .RSA_SHA1 ;
610+ }
611+
612+ msg += "&SigAlg=" + Util .urlEncoder (signAlgorithm );
613+
614+ try {
615+ signature = Util .base64encoder (Util .sign (msg , key , signAlgorithm ));
616+ } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException e ) {
617+ LOGGER .error ("buildSignature error." + e .getMessage ());
618+ }
619+
620+ if (signature .isEmpty ()) {
621+ String errorMsg = "There was a problem when calculating the Signature of the " + type ;
622+ LOGGER .error ("buildSignature error. " + errorMsg );
623+ throw new IllegalArgumentException (errorMsg );
624+ }
625+
626+ LOGGER .debug ("buildResponseSignature success. --> " + signature );
627+ return signature ;
594628 }
595629}
0 commit comments