parent
5a5464dc61
commit
be608dc76c
|
@ -425,25 +425,31 @@ Defaults to `YES` when unset.
|
|||
|The location of the SSL private key file on the filesystem that is used
|
||||
by SOGo to sign and encrypt communications with the SAML2 identity
|
||||
provider. This file must be generated for each running SOGo service
|
||||
(rather than host).
|
||||
(rather than host). Make sure this file is readable by the SOGo user.
|
||||
|
||||
|S |SOGoSAML2CertiticateLocation
|
||||
|The location of the SSL certificate file. This file must be generated
|
||||
for each running SOGo service.
|
||||
for each running SOGo service. Make sure this file is readable by the SOGo user.
|
||||
|
||||
|S |SOGoSAML2IdpMetadataLocation
|
||||
|The location of the metadata file that describes the services available
|
||||
on the SAML2 identify provider.
|
||||
on the SAML2 identify provider. The content of this file is usually generated
|
||||
directly by your SAML 2.0 IdP solution. For example, using SimpleSAMLphp, you
|
||||
can get the metadata directly from https://MYSERVER/simplesaml/saml2/idp/metadata.php
|
||||
Make sure this file is readable by the SOGo user.
|
||||
|
||||
|S |SOGoSAML2IdpPublicKeyLocation
|
||||
|The location of the SSL public key file on the filesystem that is used
|
||||
by SOGo to sign and encrypt communications with the SAML2 identity
|
||||
provider. This file should be part of the setup of your identity
|
||||
provider.
|
||||
provider. Make sure this file is readable by the SOGo user.
|
||||
|
||||
|S |SOGoSAML2IdpCertificateLocation
|
||||
|The location of the SSL certificate file. This file should be part of
|
||||
the setup of your identity provider.
|
||||
the setup of your identity provider. Make sure this file is readable by the SOGo user.
|
||||
|
||||
|S |SOGoSAML2LoginAttribute
|
||||
|The attribute provided by the IdP to identify the user in SOGo.
|
||||
|
||||
|S |SOGoSAML2LogoutEnabled
|
||||
|Boolean value indicated whether the "Logout" link is enabled when using
|
||||
|
@ -1230,13 +1236,32 @@ documentation of your identity provider and the SAML2 configuration keys
|
|||
that are listed above for proper setup. Once a SOGo instance is
|
||||
configured properly, the metadata for that instance can be retrieved
|
||||
from `http://<hostname>/SOGo/saml2-metadata` for registration with the
|
||||
identity provider.
|
||||
identity provider. SOGo will dynamically generate the metadata based on
|
||||
the SOGoSAML2CertificateLocation's content and the SOGo server name.
|
||||
|
||||
When using SimpleSAMLphp, make sure the convert OID to names by modifying your
|
||||
`metadata/saml20-idp-hosted.php` to contain something like this:
|
||||
|
||||
----
|
||||
'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
|
||||
'authproc' => array(
|
||||
100 => array('class' => 'core:AttributeMap', 'oid2name'),
|
||||
),
|
||||
----
|
||||
|
||||
If you want to test the IdP-initiated logout using SimpleSAMLphp, you can do so by opening
|
||||
the following URL:
|
||||
|
||||
----
|
||||
https://idp.example.org/simplesaml/saml2/idp/SingleLogoutService.php?ReturnTo=www.sogo.nu
|
||||
----
|
||||
|
||||
In order to relay authentication information to your IMAP server and if
|
||||
you make use of the CrudeSAML SASL plugin, you need to make sure that
|
||||
_NGImap4AuthMechanism_ is configured to use the `SAML` mechanism. If you
|
||||
make use of the CrudeSAML PAM plugin, this value may be left empty.
|
||||
|
||||
|
||||
Database Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
7
NEWS
7
NEWS
|
@ -1,8 +1,13 @@
|
|||
2.2.11 (2014-xx-xx)
|
||||
-------------------
|
||||
|
||||
Enhancements
|
||||
- Improved the SAML2 documentation
|
||||
|
||||
Bug fixes
|
||||
- Now possible to specify the username attribute for SAML2 (SOGoSAML2LoginAttribute)
|
||||
- Now possible to specify the username attribute for SAML2 (SOGoSAML2LoginAttribute) (#2381)
|
||||
- Added support for IdP-initiated SAML2 logout (#2377)
|
||||
- We now generate SAML2 metadata on the fly (#2378)
|
||||
|
||||
2.2.10 (2014-11-21)
|
||||
-------------------
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<EntityDescriptor
|
||||
entityID="%{base_url}/saml2-metadata"
|
||||
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
|
||||
<SPSSODescriptor
|
||||
AuthnRequestsSigned="true"
|
||||
WantAssertionsSigned="true"
|
||||
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>%{certificate}</ds:X509Certificate></ds:X509Data></ds:KeyInfo></KeyDescriptor><KeyDescriptor use="encryption"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data>%{certificate}<ds:X509Certificate></ds:X509Certificate></ds:X509Data></ds:KeyInfo></KeyDescriptor>
|
||||
<SingleLogoutService
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
||||
Location="%{base_url}/saml2-sls" />
|
||||
<SingleLogoutService
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
||||
Location="%{base_url}/saml2-sls" />
|
||||
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
||||
<AssertionConsumerService
|
||||
index="0"
|
||||
isDefault="true"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
||||
Location="%{base_url}/saml2-signon-post" />
|
||||
<AssertionConsumerService
|
||||
index="1"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
Location="%{base_url}/saml2/artifactResponse" />
|
||||
</SPSSODescriptor>
|
||||
</EntityDescriptor>
|
|
@ -39,7 +39,9 @@
|
|||
NSString *assertion;
|
||||
}
|
||||
|
||||
+ (NSString *) metadataInContext: (WOContext *) context;
|
||||
+ (NSString *) metadataInContext: (WOContext *) context
|
||||
certificate: (NSString *) certificate;
|
||||
|
||||
+ (NSString *) authenticationURLInContext: (WOContext *) context;
|
||||
|
||||
+ (SOGoSAML2Session *) SAML2SessionInContext: (WOContext *) context;
|
||||
|
|
|
@ -46,6 +46,28 @@
|
|||
|
||||
#import "SOGoSAML2Session.h"
|
||||
|
||||
@interface NSString (SOGoCertificateExtension)
|
||||
|
||||
- (NSString *) cleanedUpCertificate;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (SOGoCertificateExtension)
|
||||
|
||||
- (NSString *) cleanedUpCertificate
|
||||
{
|
||||
NSMutableArray *a;
|
||||
|
||||
a = [NSMutableArray arrayWithArray: [self componentsSeparatedByString: @"\n"]];
|
||||
[a removeObjectAtIndex: 0];
|
||||
[a removeLastObject];
|
||||
[a removeLastObject];
|
||||
|
||||
return [a componentsJoinedByString: @""];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface WOContext (SOGoSAML2Extension)
|
||||
|
||||
- (NSString *) SAML2ServerURLString;
|
||||
|
@ -117,7 +139,9 @@ LassoServerInContext (WOContext *context)
|
|||
format: @"certificate file '%@' could not be read",
|
||||
filename];
|
||||
|
||||
metadata = [SOGoSAML2Session metadataInContext: context];
|
||||
metadata = [SOGoSAML2Session metadataInContext: context
|
||||
certificate: certContent];
|
||||
|
||||
/* FIXME: enable key password in config ? */
|
||||
server = lasso_server_new_from_buffers ([metadata UTF8String],
|
||||
[keyContent UTF8String],
|
||||
|
@ -179,8 +203,10 @@ LassoServerInContext (WOContext *context)
|
|||
}
|
||||
|
||||
+ (NSString *) metadataInContext: (WOContext *) context
|
||||
certificate: (NSString *) certificate
|
||||
{
|
||||
NSString *metadata, *serverURLString, *filename;
|
||||
NSString *serverURLString, *filename;
|
||||
NSMutableString *metadata;
|
||||
NSBundle *bundle;
|
||||
|
||||
bundle = [NSBundle bundleForClass: self];
|
||||
|
@ -188,9 +214,16 @@ LassoServerInContext (WOContext *context)
|
|||
if (filename)
|
||||
{
|
||||
serverURLString = [context SAML2ServerURLString];
|
||||
metadata = [[NSString stringWithContentsOfFile: filename]
|
||||
stringByReplacingString: @"%{base_url}"
|
||||
withString: serverURLString];
|
||||
|
||||
metadata = [NSMutableString stringWithContentsOfFile: filename];
|
||||
[metadata replaceOccurrencesOfString: @"%{base_url}"
|
||||
withString: serverURLString
|
||||
options: 0
|
||||
range: NSMakeRange(0, [metadata length])];
|
||||
[metadata replaceOccurrencesOfString: @"%{certificate}"
|
||||
withString: [certificate cleanedUpCertificate]
|
||||
options: 0
|
||||
range: NSMakeRange(0, [metadata length])];
|
||||
}
|
||||
else
|
||||
metadata = nil;
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <SOGo/SOGoSAML2Session.h>
|
||||
#import <SOGo/SOGoSession.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
#import <SOGo/SOGoWebAuthenticator.h>
|
||||
|
||||
@interface SOGoSAML2Actions : WODirectAction
|
||||
|
@ -42,20 +44,76 @@
|
|||
|
||||
- (WOResponse *) saml2MetadataAction
|
||||
{
|
||||
NSString *metadata, *certContent;
|
||||
SOGoSystemDefaults *sd;
|
||||
WOResponse *response;
|
||||
NSString *metadata;
|
||||
|
||||
response = [context response];
|
||||
[response setHeader: @"application/xml; charset=utf-8"
|
||||
forKey: @"content-type"];
|
||||
|
||||
metadata = [SOGoSAML2Session metadataInContext: context];
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
certContent = [NSString stringWithContentsOfFile: [sd SAML2CertificateLocation]];
|
||||
|
||||
metadata = [SOGoSAML2Session metadataInContext: context
|
||||
certificate: certContent];
|
||||
|
||||
[response setContentEncoding: NSUTF8StringEncoding];
|
||||
[response appendContentString: metadata];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) saml2SingleLogoutServiceAction
|
||||
{
|
||||
NSString *userName, *value, *cookieName;
|
||||
SOGoWebAuthenticator *auth;
|
||||
WOResponse *response;
|
||||
NSCalendarDate *date;
|
||||
WOCookie *cookie;
|
||||
NSArray *creds;
|
||||
|
||||
userName = [[context activeUser] login];
|
||||
[self logWithFormat: @"SAML2 IdP-initiated SLO for user '%@'", userName];
|
||||
|
||||
response = [context response];
|
||||
|
||||
if ([userName isEqualToString: @"anonymous"])
|
||||
return response;
|
||||
|
||||
cookie = nil;
|
||||
|
||||
date = [NSCalendarDate calendarDate];
|
||||
[date setTimeZone: [NSTimeZone timeZoneWithAbbreviation: @"GMT"]];
|
||||
|
||||
// We cleanup the memecached/database session cache. We do this before
|
||||
// invoking _logoutCookieWithDate: in order to obtain its value.
|
||||
auth = [[SoApplication application] authenticatorInContext: context];
|
||||
|
||||
if ([auth respondsToSelector: @selector (cookieNameInContext:)])
|
||||
{
|
||||
cookieName = [auth cookieNameInContext: context];
|
||||
value = [[context request] cookieValueForKey: cookieName];
|
||||
creds = [auth parseCredentials: value];
|
||||
|
||||
if ([creds count] > 1)
|
||||
[SOGoSession deleteValueForSessionKey: [creds objectAtIndex: 1]];
|
||||
|
||||
if ([cookieName length])
|
||||
{
|
||||
cookie = [WOCookie cookieWithName: cookieName value: @"discard"];
|
||||
[cookie setPath: [NSString stringWithFormat: @"/%@/", [[context request] applicationName]]];
|
||||
[cookie setExpires: [date yesterday]];
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie)
|
||||
[response addCookie: cookie];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOCookie *) _authLocationResetCookieWithName: (NSString *) cookieName
|
||||
{
|
||||
WOCookie *locationCookie;
|
||||
|
|
|
@ -133,6 +133,11 @@
|
|||
actionClass = "SOGoSAML2Actions";
|
||||
actionName = "saml2SignOnPOST";
|
||||
};
|
||||
saml2-sls = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "SOGoSAML2Actions";
|
||||
actionName = "saml2SingleLogoutService";
|
||||
};
|
||||
/* saml2-signon-redirect = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "SOGoSAML2Actions";
|
||||
|
|
Loading…
Reference in New Issue